diff --git a/types/d3-sankey/d3-sankey-tests.ts b/types/d3-sankey/d3-sankey-tests.ts new file mode 100644 index 0000000000..246755a900 --- /dev/null +++ b/types/d3-sankey/d3-sankey-tests.ts @@ -0,0 +1,258 @@ +/** + * Typescript definition tests for d3/d3-sankey module + * + * Note: These tests are intended to test the definitions only + * in the sense of typing and call signature consistency. They + * are not intended as functional tests. + */ + +import * as d3Sankey from 'd3-sankey'; +import {select, Selection} from 'd3-selection'; + +// --------------------------------------------------------------------------- +// Preparatory Steps +// --------------------------------------------------------------------------- + +// Create interfaces for the user-provided node/link attributes, which are NOT mandated or calculated by +// the Sankey layout generator. The latter are reflected in the SankeyNode and SankeyLink interfaces provided +// by the definitions file +interface SNodeExtra { + nodeId: number; + name: string; +} + +interface SLinkExtra { + uom: string; +} + +// For convenience +type SNode = d3Sankey.SankeyNode; +type SLink = d3Sankey.SankeyLink; + +interface DAG { + nodes: SNode[]; + links: SLink[]; +} + +const graph: DAG = { + nodes: [{ + nodeId: 0, + name: "node0" + }, { + nodeId: 1, + name: "node1" + }, { + nodeId: 2, + name: "node2" + }, { + nodeId: 3, + name: "node3" + }, { + nodeId: 4, + name: "node4" + }], + links: [{ + source: 0, + target: 2, + value: 2, + uom: 'Widget(s)' + }, { + source: 1, + target: 2, + value: 2, + uom: 'Widget(s)' + }, { + source: 1, + target: 3, + value: 2, + uom: 'Widget(s)' + }, { + source: 0, + target: 4, + value: 2, + uom: 'Widget(s)' + }, { + source: 2, + target: 3, + value: 2, + uom: 'Widget(s)' + }, { + source: 2, + target: 4, + value: 2, + uom: 'Widget(s)' + }, { + source: 3, + target: 4, + value: 4, + uom: 'Widget(s)' + }] +}; + +let sNodes: SNode[]; +let sLinks: SLink[]; + +let num: number; +let numMaybe: number | undefined; +let str: string; +let size: [number, number]; + +const svgLinkPaths = select('svg').selectAll('.linkPath'); // assume mock DOM + +// --------------------------------------------------------------------------- +// Obtain SankeyLayout Generator +// --------------------------------------------------------------------------- + +let slgDefault: d3Sankey.SankeyLayout<{}, {}> = d3Sankey.sankey(); +let slgDAG: d3Sankey.SankeyLayout = d3Sankey.sankey(); + +// --------------------------------------------------------------------------- +// NodeWidth +// --------------------------------------------------------------------------- + +// Set ----------------------------------------------------------------------- + +// test return type for chainability +slgDAG = slgDAG.nodeWidth(32); + +// Get ----------------------------------------------------------------------- + +num = slgDAG.nodeWidth(); + +// --------------------------------------------------------------------------- +// NodePadding +// --------------------------------------------------------------------------- + +// Set ----------------------------------------------------------------------- + +// test return type for chainability +slgDAG = slgDAG.nodePadding(8); + +// Get ----------------------------------------------------------------------- + +num = slgDAG.nodePadding(); + +// --------------------------------------------------------------------------- +// Size +// --------------------------------------------------------------------------- + +// Set ----------------------------------------------------------------------- + +// test return type for chainability +slgDAG = slgDAG.size([1200, 800]); + +// Get ----------------------------------------------------------------------- + +size = slgDAG.size(); + +// --------------------------------------------------------------------------- +// Nodes +// --------------------------------------------------------------------------- + +// Set ----------------------------------------------------------------------- + +// test return type for chainability +slgDAG = slgDAG.nodes(graph.nodes); + +// Get ----------------------------------------------------------------------- + +sNodes = slgDAG.nodes(); + +// --------------------------------------------------------------------------- +// Links +// --------------------------------------------------------------------------- + +// Set ----------------------------------------------------------------------- + +// test return type for chainability +slgDAG = slgDAG.links(graph.links); + +// Get ----------------------------------------------------------------------- + +sLinks = slgDAG.links(); + +// --------------------------------------------------------------------------- +// Compute Layout +// --------------------------------------------------------------------------- + +// test return type for chainability +slgDAG = slgDAG.layout(22); + +// --------------------------------------------------------------------------- +// Relayout +// --------------------------------------------------------------------------- + +// test return type for chainability +slgDAG = slgDAG.relayout(); + +// --------------------------------------------------------------------------- +// Obtain and Use Link SVG Path Generator +// --------------------------------------------------------------------------- + +let pathGen: d3Sankey.SankeyLinkPathGenerator; + +pathGen = slgDAG.link(); + +// Adjust Link SVG Path Generator curvature ---------------------------------- + +// test return type +pathGen = pathGen.curvature(0.6); +num = pathGen.curvature(); + +// uses + +let svgPathString: string = pathGen(slgDAG.links()[0]); +svgLinkPaths.attr('d', pathGen); + +// --------------------------------------------------------------------------- +// Shape test Node/Link related interfaces and types +// --------------------------------------------------------------------------- + +// Sankey Node -------------------------------------------------------------- + +let sNode = sNodes[0]; + +// User-specified extra properties: + +num = sNode.nodeId; +str = sNode.name; + +// Sankey Layout calculated (if layout has been run, otherwise undefined): + +numMaybe = sNode.dx; +numMaybe = sNode.x; +numMaybe = sNode.dy; +numMaybe = sNode.y; +numMaybe = sNode.value; + +let linksArrMaybe: SLink[] | undefined; + +linksArrMaybe = sNode.sourceLinks; +linksArrMaybe = sNode.targetLinks; + +// Sankey Link -------------------------------------------------------------- + +let sLink = sLinks[0]; + +// User-specified extra properties: + +str = sLink.uom; + +// Sankey Layout mandated link properties: + +num = sLink.value; + +// Node depending on initialization strategy and whether +// layout(...) was invoked, the source and target nodes may be numbers +// objects without the Sankey layout coordinates, or objects with calculated +// information +let numOrSankeyNode: number | SNode; + +numOrSankeyNode = sLink.source; +numOrSankeyNode = sLink.target; + +// Sankey Layout calculated (if layout has been run, otherwise undefined): + +numMaybe = sLink.sy; +numMaybe = sLink.ty; +numMaybe = sLink.dy; diff --git a/types/d3-sankey/index.d.ts b/types/d3-sankey/index.d.ts new file mode 100644 index 0000000000..1446bc917f --- /dev/null +++ b/types/d3-sankey/index.d.ts @@ -0,0 +1,267 @@ +// Type definitions for D3JS d3-sankey module 0.4 +// Project: https://github.com/d3/d3-sankey/ +// Definitions by: Tom Wanzek , Alex Ford +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +// Last module patch version validated against: 0.4.2 + +/** + * A helper interface as an extension reference for user-provided properties of + * nodes and links in the graph, which are not required or calculated by + * the Sankey Layout Generator + */ +export interface SankeyExtraProperties { [key: string]: any; } + +/** + * Helper interface to define the properties of Sankey Nodes. Calculated properties may only be defined, + * once the layout(...) method of the Sankey layout generator has been invoked. + * + * The first generic N refers to user-defined properties contained in the node data passed into + * Sankey layout generator. These properties are IN EXCESS to the properties explicitly identified in the + * SankeyNodeMinimal interface. + * + * The second generic L refers to user-defined properties contained in the link data passed into + * Sankey layout generator. These properties are IN EXCESS to the properties explicitly identified in the + * SankeyLinkMinimal interface. + */ +export interface SankeyNodeMinimal { + /** + * Array of links which have this node as their source. + * This property is calculated internally by the Sankey layout generator. + */ + sourceLinks?: Array>; + /** + * Array of links which have this node as their target. + * This property is calculated internally by the Sankey layout generator. + */ + targetLinks?: Array>; + /** + * Node value calculated by Sankey Layout Generator based on values of incoming and outgoing links + */ + value?: number; + /** + * Node horizontal position calculated by Sankey layout generator + */ + x?: number; + /** + * Node width calculated by Sankey layout generator + */ + dx?: number; + /** + * Node vertical position (depth) calculated by Sankey layout generator + */ + y?: number; + /** + * Node height (vertical extent based on node value) calculated by Sankey layout generator + */ + dy?: number; +} + +/** + * Sankey Node type including both user-defined node data elements as well as those + * calculated once the layout(...) method of the Sankey layout generators has been invoked. + * + * The first generic N refers to user-defined properties contained in the node data passed into + * Sankey layout generator. These properties are IN EXCESS to the properties explicitly identified in the + * SankeyNodeMinimal interface. + * + * The second generic L refers to user-defined properties contained in the link data passed into + * Sankey layout generator. These properties are IN EXCESS to the properties explicitly identified in the + * SankeyLinkMinimal interface. + */ +export type SankeyNode = N & SankeyNodeMinimal; + +/** + * Helper interface to define the properties of Sankey Links. Calculated properties may only be defined, + * once the layout(...) method of the Sankey layout generator has been invoked. + * + * The first generic N refers to user-defined properties contained in the node data passed into + * Sankey layout generator. These properties are IN EXCESS to the properties explicitly identified in the + * SankeyNodeMinimal interface. + * + * The second generic L refers to user-defined properties contained in the link data passed into + * Sankey layout generator. These properties are IN EXCESS to the properties explicitly identified in the + * SankeyLinkMinimal interface. + */ +export interface SankeyLinkMinimal { + /** + * Source node of the link. For convenience, when initializing a Sankey layout, source may be the index of the source node in the nodes array + * passed into the Sankey layout generator. Once the layout(...) method is invoked, the numeric index will be replaced with the corresponding + * source node object. + */ + source: number | SankeyNode; + /** + * Target node of the link. For convenience, when initializing a Sankey layout, target may be the index of the target node in the nodes array + * passed into the Sankey layout generator. Once the layout(...) method is invoked, the numeric index will be replaced with the corresponding + * target node object. + */ + target: number | SankeyNode; + /** + * Value of the link + */ + value: number; + /** + * Link breadth calculated by Sankey layout generator based on the link value + */ + dy?: number; + /** + * Vertical starting position of the link (at source node) calculated by Sankey layout generator + */ + sy?: number; + /** + * Vertical end position of the link (at target node) calculated by Sankey layout generator + */ + ty?: number; +} + +/** + * Sankey Link type including both user-defined link data elements, those required by the Sankey layout generator, + * as well as those calculated once the layout(...) method of the layout generator has been invoked. + * + * The first generic N refers to user-defined properties contained in the node data passed into + * Sankey layout generator. These properties are IN EXCESS to the properties explicitly identified in the + * SankeyNodeMinimal interface. + * + * The second generic L refers to user-defined properties contained in the link data passed into + * Sankey layout generator. These properties are IN EXCESS to the properties explicitly identified in the + * SankeyLinkMinimal interface. + */ +export type SankeyLink = L & SankeyLinkMinimal; + +/** + * An svg path generator factory for the link paths in a calculated Sankey Layout. + */ +export interface SankeyLinkPathGenerator { + /** + * Return svg path string for a given link. + * + * IMPORTANT: Only invoke for link data with Sankey Layout information previously calculated. + * + * @param link A Sankey diagram link, for which the layout has already been calculated. + */ + (link: SankeyLink): string; + /** + * Returns the current curvature used to calculate svg paths for links. + * The default curvature is 0.5. + */ + curvature(): number; + /** + * Set the curvature used to calculate svg paths for links and return the updated link path generator. + * + * @param curvature Curvature to be used when calculating svg paths for links. The default curvature is 0.5. + */ + curvature(curvature: number): this; +} + +/** + * A Sankey layout generator. + * + * The first generic N refers to user-defined properties contained in the node data passed into + * Sankey layout generator. These properties are IN EXCESS to the properties explicitly identified in the + * SankeyNodeMinimal interface. + * + * The second generic L refers to user-defined properties contained in the link data passed into + * Sankey layout generator. These properties are IN EXCESS to the properties explicitly identified in the + * SankeyLinkMinimal interface. + */ +export interface SankeyLayout { + /** + * Return the current node width, which defaults to 24. + */ + nodeWidth(): number; + /** + * Set the node width to the specified number and return this Sankey layout generator. + * + * @param width Width of node in pixels, which defaults to 24. + */ + nodeWidth(width: number): this; + + /** + * Return the current node padding, which defaults to 8. + * + * Node padding refers to the vertical space between nodes which occupy the same horizontal space. + */ + nodePadding(): number; + /** + * Set the node padding to the specified number and return this Sankey layout generator. + * + * Node padding refers to the vertical space between nodes which occupy the same horizontal space. + * + * @param padding Node padding in pixels, which defaults to 8. + */ + nodePadding(padding: number): this; + + /** + * Return the current array of nodes, which defaults to []. + */ + nodes(): Array>; + /** + * Set the sankey generator's nodes to the specified array of objects and returns this sankey layout generator. + * + * @param nodes Array of nodes. + */ + nodes(nodes: Array>): this; + + /** + * Return the current array of links, which defaults to []. + */ + links(): Array>; + /** + * Set the sankey generator's links to the specified array of objects and returns this sankey layout generator. + * + * @param links Array of links. + */ + links(links: Array>): this; + + /** + * Runs the sankey layout algorithm updating the nodes and links with their respective layout information and returns this sankey generator. + * + * @param iterations Number of passes to be used in the iterative relaxation algorithm for node placement. + */ + layout(iterations: number): this; + + /** + * Recalculate the depth of links and return this Sankey layout generator. + * This methods is primarily used when a node is moved vertically, e.g. using d3-drag. + */ + relayout(): this; + + /** + * Return the current layout size in pixels. The size is a two element array of [width, height] which defaults to [1, 1]. + */ + size(): [number, number]; + /** + * Set the size of the layout and return this Sankey layout generator. + * + * @param size A two element array of [width, height] in pixels which defaults to [1, 1]. + */ + size(size: [number, number]): this; + + /** + * Return a Sankey link path generator for the links based on the calculated Sankey diagram layout. + * The link path generator can be invoked as a function being passed as its argument a link object + * with calculated layout information. It returns the computed path string for the link. + * By default the link path generator uses a curvature of 0.5. + */ + link(): SankeyLinkPathGenerator; +} + +/** + * Get a Sankey layout generator. + * + * Invoking sankey() without generics, means the node type and link type assume no user-defined attributes, i.e. + * only the attributes internally used by the Sankey layout generator. + */ +export function sankey(): SankeyLayout<{}, {}>; +/** + * Get a Sankey layout generator. + * + * The first generic N refers to user-defined properties contained in the node data passed into + * Sankey layout generator. These properties are IN EXCESS to the properties explicitly identified in the + * SankeyNodeMinimal interface. + * + * The second generic L refers to user-defined properties contained in the link data passed into + * Sankey layout generator. These properties are IN EXCESS to the properties explicitly identified in the + * SankeyLinkMinimal interface. + */ +export function sankey(): SankeyLayout; diff --git a/types/d3-sankey/tsconfig.json b/types/d3-sankey/tsconfig.json new file mode 100644 index 0000000000..bd11293dc2 --- /dev/null +++ b/types/d3-sankey/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6", + "dom" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "d3-sankey-tests.ts" + ] +} diff --git a/types/d3-sankey/tslint.json b/types/d3-sankey/tslint.json new file mode 100644 index 0000000000..08b1465cd6 --- /dev/null +++ b/types/d3-sankey/tslint.json @@ -0,0 +1,6 @@ +{ + "extends": "dtslint/dt.json", + "rules": { + "unified-signatures": false + } +}