{"version":3,"file":"layout.js","sourceRoot":"","sources":["../../../src/plots/sankey/layout.ts"],"names":[],"mappings":"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","sourcesContent":["import { assign, isFunction, isString } from '@antv/util';\nimport { Datum } from '../../types';\nimport { center, justify, left, right, sankey } from './sankey';\n\nconst ALIGN_METHOD = {\n left,\n right,\n center,\n justify,\n};\n\ntype InputNode = {\n readonly name: string;\n};\n\ntype InputLink = {\n readonly source: number;\n readonly target: number;\n readonly value: number;\n};\n\ntype OutputNode = {\n readonly name: string;\n readonly x0: number;\n readonly x1: number;\n readonly y0: number;\n readonly y1: number;\n readonly depth: number;\n readonly value: number;\n\n // 用于绘制 polygon\n x: number[];\n y: number[];\n};\n\ntype OutputLink = {\n readonly source: OutputNode;\n readonly target: OutputNode;\n readonly value: number;\n readonly width: number;\n readonly y0: number;\n readonly y1: number;\n\n // 用于绘制 edge\n x?: number[];\n y?: number[];\n};\n\n/**\n * 桑基图布局的数据结构定义\n */\nexport type SankeyLayoutInputData = {\n readonly nodes: InputNode[];\n readonly links: InputLink[];\n};\n\ntype SankeyLayoutOutputData = {\n readonly nodes: OutputNode[];\n readonly links: OutputLink[];\n};\n\n/**\n * 对齐方式的类型定义\n */\nexport type NodeAlign = keyof typeof ALIGN_METHOD | ((...args: any[]) => any);\n\n/**\n * 节点的 depth 自定义\n */\nexport type NodeDepth = (datum: Datum, maxDepth: number) => number;\n\n/**\n * 节点排序方法的类型定义\n */\nexport type NodeSort = (a: Datum, b: Datum) => number;\n\n/**\n * 布局参数的定义\n */\nexport type SankeyLayoutOptions = {\n readonly nodeId?: (node: Datum) => any;\n // readonly value?: (node: Datum) => any;\n // readonly source?: (edge: Datum) => any;\n // readonly target?: (edge: Datum) => any;\n // sankey.nodeSort(undefined) is the default and resorts by ascending breadth during each iteration.\n // sankey.nodeSort(null) specifies the input order of nodes and never sorts.\n // sankey.nodeSort(function) specifies the given order as a comparator function and sorts once on initialization.\n readonly nodeSort?: (a: any, b: any) => number;\n readonly nodeAlign?: NodeAlign;\n readonly nodeWidth?: number;\n readonly nodePadding?: number;\n readonly nodeDepth?: NodeDepth;\n};\n\n/**\n * 默认值\n */\nconst DEFAULT_OPTIONS: Partial = {\n nodeId: (node: Datum) => node.index,\n nodeAlign: 'justify',\n nodeWidth: 0.008,\n nodePadding: 0.03,\n nodeSort: undefined,\n};\n\n/**\n * 获得 align function\n * @param nodeAlign\n * @param nodeDepth\n */\nexport function getNodeAlignFunction(nodeAlign: NodeAlign) {\n const func = isString(nodeAlign) ? ALIGN_METHOD[nodeAlign] : isFunction(nodeAlign) ? nodeAlign : null;\n\n return func || justify;\n}\n\nexport function getDefaultOptions(sankeyLayoutOptions: SankeyLayoutOptions) {\n return assign({}, DEFAULT_OPTIONS, sankeyLayoutOptions);\n}\n\n/**\n * 桑基图利用数据进行布局的函数,最终返回节点、边的位置(0 - 1 的信息)\n * 将会修改 data 数据\n * @param sankeyLayoutOptions\n * @param data\n */\nexport function sankeyLayout(\n sankeyLayoutOptions: SankeyLayoutOptions,\n data: SankeyLayoutInputData\n): SankeyLayoutOutputData {\n const options = getDefaultOptions(sankeyLayoutOptions);\n\n const { nodeId, nodeSort, nodeAlign, nodeWidth, nodePadding, nodeDepth } = options;\n\n const sankeyProcessor = sankey()\n // .links((d: any) => d.links)\n // .nodes((d: any) => d.nodes)\n .nodeSort(nodeSort)\n .nodeWidth(nodeWidth)\n .nodePadding(nodePadding)\n .nodeDepth(nodeDepth)\n .nodeAlign(getNodeAlignFunction(nodeAlign))\n .extent([\n [0, 0],\n [1, 1],\n ])\n .nodeId(nodeId);\n\n // 进行桑基图布局处理\n const layoutData: SankeyLayoutOutputData = sankeyProcessor(data);\n\n // post process (x, y), etc.\n const nodes = layoutData.nodes\n .map((node) => {\n const { x0, x1, y0, y1 } = node;\n /* points\n * 3---2\n * | |\n * 0---1\n */\n node.x = [x0, x1, x1, x0];\n node.y = [y0, y0, y1, y1];\n\n return node;\n })\n .filter((node) => {\n return node.name !== null;\n });\n\n const links = layoutData.links\n .map((edge) => {\n const { source, target } = edge;\n const sx = source.x1;\n const tx = target.x0;\n edge.x = [sx, sx, tx, tx];\n const offset = edge.width / 2;\n edge.y = [edge.y0 + offset, edge.y0 - offset, edge.y1 + offset, edge.y1 - offset];\n\n return edge;\n })\n .filter((edge) => {\n const { source, target } = edge;\n return source.name !== null && target.name !== null;\n });\n\n return { nodes, links };\n}\n"]}