graphs-and-paths
Advanced tools
Comparing version
import { Edge, EdgeId, EdgePoint, Location, Node, NodeId, Path, SimpleEdge, SimpleNode } from "./types"; | ||
/** | ||
* A graph composed of [[Node]]s and [[Edge]]s, representing 2-D spatial points and links between | ||
* them. Provides methods for reading and analyzing its data. | ||
* | ||
* The graph and all its data are immutable. No method will modify the `Graph` instance on which it | ||
* is called, although some will return new instances. | ||
* | ||
* New `Graph` instances are created using [[Graph.create]], which takes [[SimpleNode]]s and | ||
* [[SimpleEdge]]s as arguments. Upon construction, the graph creates corresponding [[Node]] and | ||
* [[Edge]] instances which contain additional information. All `Graph` methods will return these | ||
* `Node`s rather than the original `SimpleNode`s, and likewise for edges. | ||
* | ||
* Example usage: | ||
* ``` javascript | ||
* import Graph from "graphs-and-paths"; | ||
* | ||
* const nodes = [ | ||
* { id: "A", location: { x: 0, y: 0 } }, | ||
* { id: "B", location: { x: 3, y: 0 } }, | ||
* { id: "C", location: { x: 0, y: 4 } } | ||
* ]; | ||
* const edges = [ | ||
* { id: "AB", startNodeId: "A", endNodeId: "B" }, | ||
* { id: "BC", startNodeId: "B", endNodeId: "C" }, | ||
* { id: "CA", startNodeId: "C", endNodeId: "A" } | ||
* ]; | ||
* const graph = Graph.create(nodes, edges); | ||
* | ||
* graph.getNode("A"); | ||
* // { id: "A", location: { x: 0, y: 0 }, edgeIds: ["AB", "CA"] } | ||
* | ||
* graph.getLocation("AB", 2); | ||
* // { x: 2, y: 0 } | ||
* | ||
* graph.getShortestPath( | ||
* { edgeId: "CA", distance: 3 }, | ||
* { edgeId: "BC", distance: 1 } | ||
* ).locations; | ||
* // [ | ||
* // { x: 0, y: 1 }, | ||
* // { x: 0, y: 0 }, | ||
* // { x: 3, y: 0 }, | ||
* // { x: 2.4, y: 0.8 } | ||
* // ] | ||
* ``` | ||
*/ | ||
export default class Graph { | ||
@@ -6,17 +52,110 @@ private readonly nodesById; | ||
private readonly mesh; | ||
/** | ||
* @param nodes A list of nodes. | ||
* @param edges A list of edges. | ||
* @returns A new `Graph` instance with the specified nodes and edges. | ||
*/ | ||
static create(nodes: SimpleNode[], edges: SimpleEdge[]): Graph; | ||
/** | ||
* @param location1 A location. | ||
* @param location2 Another location. | ||
* @returns The straight-line distance between `location1` and `location2`. | ||
*/ | ||
static distance(location1: Location, location2: Location): number; | ||
/** | ||
* Helper function for computing progress down a path after advancing along it for a given | ||
* distance. If the distance is greater than the total length of the path, then advances to | ||
* the end of the path. Throws on negative distances. | ||
* | ||
* @param locations A list of locations representing a path. | ||
* @param distance A distance down the path. | ||
* @returns A new list of locations representing the remaining part of `locations` after | ||
* advancing `distance` along the path. | ||
*/ | ||
static advanceAlongLocations(locations: Location[], distance: number): Location[]; | ||
private constructor(nodesById, edgesById, mesh?); | ||
/** | ||
* @returns All the nodes present in this graph, in the order that they were originally provided | ||
* to [[Graph.create]]. | ||
*/ | ||
getAllNodes(): Node[]; | ||
/** | ||
* @returns All the edges present in this graph, in the order that they were originally provided | ||
* to [[Graph.create]]. | ||
*/ | ||
getAllEdges(): Edge[]; | ||
/** | ||
* @param nodeId A node ID. | ||
* @returns The `Node` associated with the given ID, or `undefined` if none exists. Note that | ||
* the type signature is a lie (it does not claim to be nullable), but this is | ||
* consistent with other lookup methods such as keyed-indexing. | ||
*/ | ||
getNode(nodeId: NodeId): Node; | ||
/** | ||
* @param edgeId An edge ID. | ||
* @returns The `Edge` associated with the given ID, or `undefined` if none exists. Note that | ||
* the type signature is a lie (it does not claim to be nullable), but this is | ||
* consistent with other lookup methods such as keyed-indexing. | ||
*/ | ||
getEdge(edgeId: EdgeId): Edge; | ||
/** | ||
* @param nodeId A node ID. | ||
* @returns All edges which have the node with the given ID as an endpoint. | ||
*/ | ||
getEdgesOfNode(nodeId: NodeId): Edge[]; | ||
/** | ||
* @param edgeId An edge ID. | ||
* @returns The two nodes which are endpoints of the edge with the given ID. | ||
*/ | ||
getEndpointsOfEdge(edgeId: EdgeId): [Node, Node]; | ||
/** | ||
* Given an edge and one of its endpoints, return the other endpoint. Throws if either of the | ||
* IDs is nonexistent, or if the node is not an endpoint of the edge. | ||
* | ||
* @param edgeId An edge ID. | ||
* @param nodeId A node ID, referencing one of the endpoints of the edge. | ||
* @returns The node which is the other endpoint of the edge with the given ID. | ||
*/ | ||
getOtherEndpoint(edgeId: EdgeId, nodeId: NodeId): Node; | ||
/** | ||
* @param nodeId A node ID. | ||
* @return All nodes which are connected to the node with the given ID by an edge. | ||
*/ | ||
getNeighbors(nodeId: NodeId): Node[]; | ||
/** | ||
* @param edgePoint A point specified as a certain distance along an edge. | ||
* @return The Cartesian coordinates of the given point. | ||
*/ | ||
getLocation(edgePoint: EdgePoint): Location; | ||
/** | ||
* Creates a new `Graph` instance with the same shape but with a reduced number of nodes and | ||
* edges. Each instance of multiple nodes and edges in a chain with no forks is converted into a | ||
* single edge, where the removed nodes are converted into inner locations of the new edge. In | ||
* particular, the new graph will have no nodes of degree 2. This may significantly increase | ||
* the speed of certain calculations, such as [[getShortestPath]]. | ||
* | ||
* A newly created edge will have the lowest ID of the edges which were combined to form it, | ||
* where numbers are considered lower than strings. | ||
* | ||
* @returns A new coalesced `Graph` instance. | ||
*/ | ||
coalesced(): Graph; | ||
/** | ||
* @returns A list of new `Graph` instances, each representing a single connected component of | ||
* this instance. | ||
*/ | ||
getConnectedComponents(): Graph[]; | ||
/** | ||
* @param nodeId A node ID. | ||
* @returns A new `Graph` instance representing the connected component containing the node with | ||
* the given ID. | ||
*/ | ||
getConnectedComponentOfNode(nodeId: NodeId): Graph; | ||
/** | ||
* Returns the shortest path between two points on the graph. Throws if no such path exists. | ||
* | ||
* @param start A point along the graph. | ||
* @param end Another point along the graph. | ||
* @returns The shortest path from the first point to the second. | ||
*/ | ||
getShortestPath(start: EdgePoint, end: EdgePoint): Path; | ||
@@ -26,8 +165,28 @@ /** | ||
* the start point of the path moves forward, and any nodes and edges that it passes are | ||
* dropped. | ||
* dropped. Throws an error if distance is negative. | ||
* | ||
* Throws an error if distance is negative. | ||
* @param path A path. | ||
* @param distance A distance to travel along the path. | ||
* @returns The remaining portion of `path` after traveling `distance` along it. | ||
*/ | ||
advanceAlongPath(path: Path, distance: number): Path; | ||
/** | ||
* Does preprocessing to enable [[getClosestPoint]] by creating a spatial index for mesh of | ||
* points along the graph. | ||
* | ||
* @param precision How fine the mesh should be. Lower precision is more accurate but takes | ||
* more time to precompute and more memory. As a rule-of-thumb, [[getClosestPoint]] will | ||
* be accurate to within `precision` distance. | ||
* @returns A new `Graph` instance with a spatial index enabled. | ||
*/ | ||
withClosestPointMesh(precision: number): Graph; | ||
/** | ||
* Returns the closest point on the graph to a given location. This requires the graph to have | ||
* a spatial index. To enable this, first use [[withClosestPointMesh]] to obtain a new graph | ||
* instance with an index enabled. Calling this method on a graph with no index will throw. | ||
* | ||
* @param location A location. | ||
* @returns The point on the graph closest to the given location, up to a precision determined | ||
* by the graph's mesh. | ||
*/ | ||
getClosestPoint(location: Location): EdgePoint; | ||
@@ -34,0 +193,0 @@ private getNodeOrThrow(nodeId); |
@@ -6,2 +6,48 @@ "use strict"; | ||
var Utils = require("./utils"); | ||
/** | ||
* A graph composed of [[Node]]s and [[Edge]]s, representing 2-D spatial points and links between | ||
* them. Provides methods for reading and analyzing its data. | ||
* | ||
* The graph and all its data are immutable. No method will modify the `Graph` instance on which it | ||
* is called, although some will return new instances. | ||
* | ||
* New `Graph` instances are created using [[Graph.create]], which takes [[SimpleNode]]s and | ||
* [[SimpleEdge]]s as arguments. Upon construction, the graph creates corresponding [[Node]] and | ||
* [[Edge]] instances which contain additional information. All `Graph` methods will return these | ||
* `Node`s rather than the original `SimpleNode`s, and likewise for edges. | ||
* | ||
* Example usage: | ||
* ``` javascript | ||
* import Graph from "graphs-and-paths"; | ||
* | ||
* const nodes = [ | ||
* { id: "A", location: { x: 0, y: 0 } }, | ||
* { id: "B", location: { x: 3, y: 0 } }, | ||
* { id: "C", location: { x: 0, y: 4 } } | ||
* ]; | ||
* const edges = [ | ||
* { id: "AB", startNodeId: "A", endNodeId: "B" }, | ||
* { id: "BC", startNodeId: "B", endNodeId: "C" }, | ||
* { id: "CA", startNodeId: "C", endNodeId: "A" } | ||
* ]; | ||
* const graph = Graph.create(nodes, edges); | ||
* | ||
* graph.getNode("A"); | ||
* // { id: "A", location: { x: 0, y: 0 }, edgeIds: ["AB", "CA"] } | ||
* | ||
* graph.getLocation("AB", 2); | ||
* // { x: 2, y: 0 } | ||
* | ||
* graph.getShortestPath( | ||
* { edgeId: "CA", distance: 3 }, | ||
* { edgeId: "BC", distance: 1 } | ||
* ).locations; | ||
* // [ | ||
* // { x: 0, y: 1 }, | ||
* // { x: 0, y: 0 }, | ||
* // { x: 3, y: 0 }, | ||
* // { x: 2.4, y: 0.8 } | ||
* // ] | ||
* ``` | ||
*/ | ||
var Graph = (function () { | ||
@@ -13,2 +59,7 @@ function Graph(nodesById, edgesById, mesh) { | ||
} | ||
/** | ||
* @param nodes A list of nodes. | ||
* @param edges A list of edges. | ||
* @returns A new `Graph` instance with the specified nodes and edges. | ||
*/ | ||
Graph.create = function (nodes, edges) { | ||
@@ -57,2 +108,20 @@ var nodesById = new Map(); | ||
}; | ||
/** | ||
* @param location1 A location. | ||
* @param location2 Another location. | ||
* @returns The straight-line distance between `location1` and `location2`. | ||
*/ | ||
Graph.distance = function (location1, location2) { | ||
return Utils.distanceBetween(location1, location2); | ||
}; | ||
/** | ||
* Helper function for computing progress down a path after advancing along it for a given | ||
* distance. If the distance is greater than the total length of the path, then advances to | ||
* the end of the path. Throws on negative distances. | ||
* | ||
* @param locations A list of locations representing a path. | ||
* @param distance A distance down the path. | ||
* @returns A new list of locations representing the remaining part of `locations` after | ||
* advancing `distance` along the path. | ||
*/ | ||
Graph.advanceAlongLocations = function (locations, distance) { | ||
@@ -82,14 +151,38 @@ if (distance < 0) { | ||
}; | ||
/** | ||
* @returns All the nodes present in this graph, in the order that they were originally provided | ||
* to [[Graph.create]]. | ||
*/ | ||
Graph.prototype.getAllNodes = function () { | ||
return Array.from(this.nodesById.values()); | ||
}; | ||
/** | ||
* @returns All the edges present in this graph, in the order that they were originally provided | ||
* to [[Graph.create]]. | ||
*/ | ||
Graph.prototype.getAllEdges = function () { | ||
return Array.from(this.edgesById.values()); | ||
}; | ||
/** | ||
* @param nodeId A node ID. | ||
* @returns The `Node` associated with the given ID, or `undefined` if none exists. Note that | ||
* the type signature is a lie (it does not claim to be nullable), but this is | ||
* consistent with other lookup methods such as keyed-indexing. | ||
*/ | ||
Graph.prototype.getNode = function (nodeId) { | ||
return this.nodesById.get(nodeId); | ||
}; | ||
/** | ||
* @param edgeId An edge ID. | ||
* @returns The `Edge` associated with the given ID, or `undefined` if none exists. Note that | ||
* the type signature is a lie (it does not claim to be nullable), but this is | ||
* consistent with other lookup methods such as keyed-indexing. | ||
*/ | ||
Graph.prototype.getEdge = function (edgeId) { | ||
return this.edgesById.get(edgeId); | ||
}; | ||
/** | ||
* @param nodeId A node ID. | ||
* @returns All edges which have the node with the given ID as an endpoint. | ||
*/ | ||
Graph.prototype.getEdgesOfNode = function (nodeId) { | ||
@@ -99,2 +192,6 @@ var _this = this; | ||
}; | ||
/** | ||
* @param edgeId An edge ID. | ||
* @returns The two nodes which are endpoints of the edge with the given ID. | ||
*/ | ||
Graph.prototype.getEndpointsOfEdge = function (edgeId) { | ||
@@ -104,2 +201,10 @@ var _a = this.getEdgeOrThrow(edgeId), startNodeId = _a.startNodeId, endNodeId = _a.endNodeId; | ||
}; | ||
/** | ||
* Given an edge and one of its endpoints, return the other endpoint. Throws if either of the | ||
* IDs is nonexistent, or if the node is not an endpoint of the edge. | ||
* | ||
* @param edgeId An edge ID. | ||
* @param nodeId A node ID, referencing one of the endpoints of the edge. | ||
* @returns The node which is the other endpoint of the edge with the given ID. | ||
*/ | ||
Graph.prototype.getOtherEndpoint = function (edgeId, nodeId) { | ||
@@ -117,2 +222,6 @@ var edge = this.getEdgeOrThrow(edgeId); | ||
}; | ||
/** | ||
* @param nodeId A node ID. | ||
* @return All nodes which are connected to the node with the given ID by an edge. | ||
*/ | ||
Graph.prototype.getNeighbors = function (nodeId) { | ||
@@ -123,2 +232,6 @@ var _this = this; | ||
}; | ||
/** | ||
* @param edgePoint A point specified as a certain distance along an edge. | ||
* @return The Cartesian coordinates of the given point. | ||
*/ | ||
Graph.prototype.getLocation = function (edgePoint) { | ||
@@ -139,2 +252,14 @@ var edgeId = edgePoint.edgeId, distance = edgePoint.distance; | ||
}; | ||
/** | ||
* Creates a new `Graph` instance with the same shape but with a reduced number of nodes and | ||
* edges. Each instance of multiple nodes and edges in a chain with no forks is converted into a | ||
* single edge, where the removed nodes are converted into inner locations of the new edge. In | ||
* particular, the new graph will have no nodes of degree 2. This may significantly increase | ||
* the speed of certain calculations, such as [[getShortestPath]]. | ||
* | ||
* A newly created edge will have the lowest ID of the edges which were combined to form it, | ||
* where numbers are considered lower than strings. | ||
* | ||
* @returns A new coalesced `Graph` instance. | ||
*/ | ||
Graph.prototype.coalesced = function () { | ||
@@ -156,7 +281,7 @@ var _this = this; | ||
var minEdgeId = Utils.min(path.map(function (pathEdge) { return pathEdge.edge.id; }), Utils.compareIds); | ||
var locations = Utils.dedupeLocations(Utils.flatMap(path, function (pathEdge) { | ||
var allLocations = Utils.dedupeLocations(Utils.flatMap(path, function (pathEdge) { | ||
var locations = pathEdge.edge.locations, isForward = pathEdge.isForward; | ||
return isForward ? locations : locations.slice().reverse(); | ||
})); | ||
var innerLocations = locations.slice(1, locations.length - 1); | ||
var innerLocations = allLocations.slice(1, allLocations.length - 1); | ||
var newEdge = { | ||
@@ -179,2 +304,6 @@ id: minEdgeId, | ||
}; | ||
/** | ||
* @returns A list of new `Graph` instances, each representing a single connected component of | ||
* this instance. | ||
*/ | ||
Graph.prototype.getConnectedComponents = function () { | ||
@@ -193,2 +322,7 @@ var _this = this; | ||
}; | ||
/** | ||
* @param nodeId A node ID. | ||
* @returns A new `Graph` instance representing the connected component containing the node with | ||
* the given ID. | ||
*/ | ||
Graph.prototype.getConnectedComponentOfNode = function (nodeId) { | ||
@@ -214,2 +348,9 @@ var startNode = this.getNodeOrThrow(nodeId); | ||
}; | ||
/** | ||
* Returns the shortest path between two points on the graph. Throws if no such path exists. | ||
* | ||
* @param start A point along the graph. | ||
* @param end Another point along the graph. | ||
* @returns The shortest path from the first point to the second. | ||
*/ | ||
Graph.prototype.getShortestPath = function (start, end) { | ||
@@ -282,5 +423,7 @@ var _this = this; | ||
* the start point of the path moves forward, and any nodes and edges that it passes are | ||
* dropped. | ||
* dropped. Throws an error if distance is negative. | ||
* | ||
* Throws an error if distance is negative. | ||
* @param path A path. | ||
* @param distance A distance to travel along the path. | ||
* @returns The remaining portion of `path` after traveling `distance` along it. | ||
*/ | ||
@@ -330,2 +473,11 @@ Graph.prototype.advanceAlongPath = function (path, distance) { | ||
}; | ||
/** | ||
* Does preprocessing to enable [[getClosestPoint]] by creating a spatial index for mesh of | ||
* points along the graph. | ||
* | ||
* @param precision How fine the mesh should be. Lower precision is more accurate but takes | ||
* more time to precompute and more memory. As a rule-of-thumb, [[getClosestPoint]] will | ||
* be accurate to within `precision` distance. | ||
* @returns A new `Graph` instance with a spatial index enabled. | ||
*/ | ||
Graph.prototype.withClosestPointMesh = function (precision) { | ||
@@ -358,2 +510,11 @@ var _this = this; | ||
}; | ||
/** | ||
* Returns the closest point on the graph to a given location. This requires the graph to have | ||
* a spatial index. To enable this, first use [[withClosestPointMesh]] to obtain a new graph | ||
* instance with an index enabled. Calling this method on a graph with no index will throw. | ||
* | ||
* @param location A location. | ||
* @returns The point on the graph closest to the given location, up to a precision determined | ||
* by the graph's mesh. | ||
*/ | ||
Graph.prototype.getClosestPoint = function (location) { | ||
@@ -360,0 +521,0 @@ if (this.mesh) { |
@@ -0,40 +1,164 @@ | ||
/** | ||
* The type of the identifier for a [[Node]]. | ||
*/ | ||
export declare type NodeId = string | number; | ||
/** | ||
* The type of the identifier for an [[Edge]]. | ||
*/ | ||
export declare type EdgeId = string | number; | ||
/** | ||
* Basic information about a node used to initially create a [[Graph]]. Once a graph is constructed, | ||
* all of its methods will return [[Node]]s instead, which contain additional useful information. | ||
*/ | ||
export interface SimpleNode { | ||
/** | ||
* An identifier, unique across all nodes in a given [[Graph]]. | ||
*/ | ||
id: NodeId; | ||
/** | ||
* The location of the node. | ||
*/ | ||
location: Location; | ||
} | ||
/** | ||
* Basic information about an edge used to initially create a [[Graph]]. Once a graph is | ||
* constructed, all of its methods will return [[Edge]]s instead, which contain additional useful | ||
* information. | ||
* | ||
* An edge is specified by which nodes are its "start" and "end." The direction of an edge is | ||
* arbitrary, but once set will be handled consistently by the [[Graph]] methods. | ||
* | ||
* The edge may also specify internal locations which it passes through on its way between its | ||
* endpoints. That is, an edge may curve and does not necessarily represent a physical straight | ||
* line. | ||
*/ | ||
export interface SimpleEdge { | ||
/** | ||
* An identifier, unique across all edges in a given [[Graph]]. | ||
*/ | ||
id: EdgeId; | ||
/** | ||
* ID of the [[Node]] at the start of this edge. | ||
*/ | ||
startNodeId: NodeId; | ||
/** | ||
* ID of the [[Node]] at the end of the edge. | ||
*/ | ||
endNodeId: NodeId; | ||
/** | ||
* Additional locations that the edge passes through which are not represented by [[Node]]s. | ||
*/ | ||
innerLocations?: Location[]; | ||
} | ||
/** | ||
* A node in a [[Graph]]. Like a [[SimpleNode]], but with additional information for convenience | ||
* and efficiency. | ||
*/ | ||
export interface Node extends SimpleNode { | ||
/** | ||
* The IDs of all [[Edge]]s for which this node is an endpoint. | ||
*/ | ||
edgeIds: EdgeId[]; | ||
} | ||
/** | ||
* An edge in a [[Graph]]. Like a [[SimpleEdge]], but with additional information for convenience | ||
* and efficiency. | ||
* | ||
* An edge is specified by which nodes are its "start" and "end." The direction of an edge is | ||
* arbitrary, but once set will be handled consistently by the `Graph` methods. | ||
* | ||
* The edge may also specify internal locations which it passes through on its way between its | ||
* endpoints. That is, an edge may curve and does not necessarily represent a physical straight | ||
* line. | ||
*/ | ||
export interface Edge extends SimpleEdge { | ||
/** | ||
* The total length of this edge. | ||
*/ | ||
length: number; | ||
/** | ||
* The locations which make up this edge from start to finish. Like [[innerLocations]], but | ||
* including the locations of the start and end [[Node]]s. | ||
*/ | ||
locations: Location[]; | ||
/** | ||
* The cumulative distances of each location along the path. This array will always have the | ||
* same number of elements as [[locations]]. `locationDistances[i]` is the total distance one | ||
* must travel along the edge to arrive at `locations[i]`. In particular, this means that | ||
* `locationDistances[0]` is always `0` and `locationDistances[locations.length - 1]` is always | ||
* [[length]]. | ||
*/ | ||
locationDistances: number[]; | ||
} | ||
/** | ||
* A single point in a 2-d Cartesian coordinate system. | ||
*/ | ||
export interface Location { | ||
/** | ||
* The x-coordinate. | ||
*/ | ||
x: number; | ||
/** | ||
* The y-coordinate. | ||
*/ | ||
y: number; | ||
} | ||
/** | ||
* A point which lies partway along an [[Edge]]. | ||
*/ | ||
export interface EdgePoint { | ||
/** | ||
* The ID of the [[Edge]] on which this point lies. | ||
*/ | ||
edgeId: EdgeId; | ||
/** | ||
* The distance along the edge from the start node at which this point lies. | ||
*/ | ||
distance: number; | ||
} | ||
/** | ||
* An [[Edge]] along with a direction (forwards or backwards). Useful for communicating directed | ||
* paths. | ||
*/ | ||
export interface OrientedEdge { | ||
/** | ||
* The edge. | ||
*/ | ||
edge: Edge; | ||
/** | ||
* True if the desired orientation is in the direction from the edge's start node to its end. | ||
*/ | ||
isForward: boolean; | ||
} | ||
/** | ||
* A path along edges of the graph from one [[EdgePoint]] to another. Contains various pieces of | ||
* information used to describe this path. | ||
*/ | ||
export interface Path { | ||
/** | ||
* The point at which this path starts. | ||
*/ | ||
start: EdgePoint; | ||
/** | ||
* The point at which this path ends. | ||
*/ | ||
end: EdgePoint; | ||
/** | ||
* The edges that make up this path, along with which direction the path travels across | ||
* each. | ||
*/ | ||
orientedEdges: OrientedEdge[]; | ||
/** | ||
* The nodes which are crossed by this path in the order of crossing. | ||
*/ | ||
nodes: Node[]; | ||
/** | ||
* The locations which make up this path. That is, the path can be drawn by connecting these | ||
* locations with line segments. | ||
*/ | ||
locations: Location[]; | ||
/** | ||
* The total length of the path. | ||
*/ | ||
length: number; | ||
} |
@@ -0,2 +1,7 @@ | ||
/** | ||
* Collection of helper methods. These are not exported, and all functions in this file should be | ||
* marked @hidden. | ||
*/ | ||
import { Location, OrientedEdge } from "./types"; | ||
/** @hidden */ | ||
export declare function last<T>(ts: T[]): T; | ||
@@ -9,2 +14,4 @@ /** | ||
* of the path. | ||
* | ||
* @hidden | ||
*/ | ||
@@ -15,12 +22,22 @@ export declare function getCumulativeDistances(path: Location[]): number[]; | ||
* elements xs are larger than x, then return -1. | ||
* | ||
* @hidden | ||
*/ | ||
export declare function findFloorIndex(xs: number[], x: number): number; | ||
/** @hidden */ | ||
export declare function getIntermediateLocation(start: Location, end: Location, distance: number): Location; | ||
/** @hidden */ | ||
export declare function distanceBetween(location1: Location, location2: Location): number; | ||
/** @hidden */ | ||
export declare function compareIds(id1: number | string, id2: number | string): 0 | 1 | -1; | ||
/** @hidden */ | ||
export declare function reversePath(edges: OrientedEdge[]): OrientedEdge[]; | ||
/** @hidden */ | ||
export declare function flatMap<T, U>(array: T[], f: (t: T) => U[]): U[]; | ||
/** @hidden */ | ||
export declare function min<T>(array: T[], comparator: (t1: T, t2: T) => number): T; | ||
/** | ||
* Returns information about the closest point on segment ab to point p. | ||
* | ||
* @hidden | ||
*/ | ||
@@ -31,4 +48,7 @@ export declare function closestPointOnSegment(p: Location, a: Location, b: Location): { | ||
}; | ||
/** @hidden */ | ||
export declare function areLocationsEqual(location1: Location, location2: Location): boolean; | ||
/** @hidden */ | ||
export declare function dedupeLocations(locations: Location[]): Location[]; | ||
/** @hidden */ | ||
export declare function pushAll<T>(array: T[], toAdd: T[]): T[]; |
"use strict"; | ||
/** @hidden */ | ||
function last(ts) { | ||
@@ -15,2 +16,4 @@ if (ts.length === 0) { | ||
* of the path. | ||
* | ||
* @hidden | ||
*/ | ||
@@ -35,2 +38,4 @@ function getCumulativeDistances(path) { | ||
* elements xs are larger than x, then return -1. | ||
* | ||
* @hidden | ||
*/ | ||
@@ -57,2 +62,3 @@ function findFloorIndex(xs, x) { | ||
exports.findFloorIndex = findFloorIndex; | ||
/** @hidden */ | ||
function getIntermediateLocation(start, end, distance) { | ||
@@ -67,5 +73,7 @@ var length = distanceBetween(start, end); | ||
exports.getIntermediateLocation = getIntermediateLocation; | ||
/** @hidden */ | ||
function clamp(x, min, max) { | ||
return Math.max(min, Math.min(max, x)); | ||
} | ||
/** @hidden */ | ||
function distanceBetween(location1, location2) { | ||
@@ -77,2 +85,3 @@ var dx = location2.x - location1.x; | ||
exports.distanceBetween = distanceBetween; | ||
/** @hidden */ | ||
function compareIds(id1, id2) { | ||
@@ -99,2 +108,3 @@ // Numbers before strings, then natural order. | ||
exports.compareIds = compareIds; | ||
/** @hidden */ | ||
function reversePath(edges) { | ||
@@ -109,2 +119,3 @@ return edges | ||
exports.reversePath = reversePath; | ||
/** @hidden */ | ||
function flatMap(array, f) { | ||
@@ -114,2 +125,3 @@ return array.reduce(function (result, t) { return pushAll(result, f(t)); }, []); | ||
exports.flatMap = flatMap; | ||
/** @hidden */ | ||
function min(array, comparator) { | ||
@@ -124,2 +136,4 @@ if (array.length === 0) { | ||
* Returns information about the closest point on segment ab to point p. | ||
* | ||
* @hidden | ||
*/ | ||
@@ -144,2 +158,3 @@ function closestPointOnSegment(p, a, b) { | ||
exports.closestPointOnSegment = closestPointOnSegment; | ||
/** @hidden */ | ||
function areLocationsEqual(location1, location2) { | ||
@@ -149,2 +164,3 @@ return location1.x === location2.x && location1.y === location2.y; | ||
exports.areLocationsEqual = areLocationsEqual; | ||
/** @hidden */ | ||
function dedupeLocations(locations) { | ||
@@ -154,2 +170,3 @@ return dedupe(locations, areLocationsEqual); | ||
exports.dedupeLocations = dedupeLocations; | ||
/** @hidden */ | ||
function dedupe(ts, equals) { | ||
@@ -165,2 +182,3 @@ if (equals === void 0) { equals = (function (t1, t2) { return t1 === t2; }); } | ||
} | ||
/** @hidden */ | ||
function pushAll(array, toAdd) { | ||
@@ -167,0 +185,0 @@ toAdd.forEach(function (t) { return array.push(t); }); |
{ | ||
"name": "graphs-and-paths", | ||
"version": "0.1.4", | ||
"description": "Tools for graphs representing physical locations.", | ||
"version": "0.2.0", | ||
"description": "Tools for graphs representing 2-D spatial points and links between them.", | ||
"main": "dist/index.js", | ||
@@ -13,2 +13,3 @@ "types": "dist/index", | ||
"build": "npm run clean && tsc", | ||
"buildDocs": "typedoc --out docs --mode file --name 'Graphs and Paths' --readme none --module commonjs --target es5 --theme minimal --excludePrivate", | ||
"jest": "jest --config jest.json", | ||
@@ -46,2 +47,4 @@ "jest-watch": "npm run jest -- --watch", | ||
"tslint": "^4.1.1", | ||
"typedoc": "^0.5.3", | ||
"typedoc-default-themes": "0.4.0", | ||
"typescript": "^2.1.4" | ||
@@ -48,0 +51,0 @@ }, |
# Graphs and Paths | ||
Tools for graphs representing physical locations. | ||
Tools for graphs representing 2-D spatial points and links between them. [View the demo here](https://dphilipson.github.io/graphs-and-paths-demo). | ||
[](https://travis-ci.org/dphilipson/graphs-and-paths) | ||
## Installation | ||
``` | ||
npm install --save graphs-and-paths | ||
``` | ||
## API | ||
[View full documentation](https://dphilipson.github.io/graphs-and-paths). | ||
## Sample Usage | ||
``` javascript | ||
import Graph from "graphs-and-paths"; | ||
const nodes = [ | ||
{ id: "A", location: { x: 0, y: 0 } }, | ||
{ id: "B", location: { x: 3, y: 0 } }, | ||
{ id: "C", location: { x: 0, y: 4 } } | ||
]; | ||
const edges = [ | ||
{ id: "AB", startNodeId: "A", endNodeId: "B" }, | ||
{ id: "BC", startNodeId: "B", endNodeId: "C" }, | ||
{ id: "CA", startNodeId: "C", endNodeId: "A" } | ||
]; | ||
const graph = Graph.create(nodes, edges); | ||
graph.getNode("A"); | ||
// { id: "A", location: { x: 0, y: 0 }, edgeIds: ["AB", "CA"] } | ||
graph.getLocation("AB", 2); | ||
// { x: 2, y: 0 } | ||
graph.getShortestPath( | ||
{ edgeId: "CA", distance: 3 }, | ||
{ edgeId: "BC", distance: 1 } | ||
).locations; | ||
// [ | ||
// { x: 0, y: 1 }, | ||
// { x: 0, y: 0 }, | ||
// { x: 3, y: 0 }, | ||
// { x: 2.4, y: 0.8 } | ||
// ] | ||
``` | ||
Many more methods are available. | ||
[View full documentation](https://dphilipson.github.io/graphs-and-paths) for details. | ||
Copyright © 2016 David Philipson |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
86140
30.68%1308
58.35%54
575%9
28.57%