diff --git a/packages/plots/src/core/plots/sankey/adaptor.ts b/packages/plots/src/core/plots/sankey/adaptor.ts index 7eefdc0ce3..57c4c8cd6c 100644 --- a/packages/plots/src/core/plots/sankey/adaptor.ts +++ b/packages/plots/src/core/plots/sankey/adaptor.ts @@ -1,6 +1,6 @@ import { mark } from '../../adaptor'; import type { Adaptor } from '../../types'; -import { flow, transformOptions } from '../../utils'; +import { flow, isArray, set, transformOptions } from '../../utils'; import type { SankeyOptions } from './type'; type Params = Adaptor; @@ -10,5 +10,22 @@ type Params = Adaptor; * @param options */ export function adaptor(params: Params) { - return flow(mark, transformOptions)(params); + const init = (params: Params) => { + const { options } = params; + const { data } = options; + if (isArray(data)) { + const dataCfg = { + value: data, + transform: [ + { + type: 'custom', + callback: (datum) => ({ links: datum }), + }, + ], + }; + set(options, 'data', dataCfg); + } + return params; + }; + return flow(init, mark, transformOptions)(params); } diff --git a/packages/plots/src/core/plots/sankey/index.ts b/packages/plots/src/core/plots/sankey/index.ts index 300b908e07..ca1c64b494 100644 --- a/packages/plots/src/core/plots/sankey/index.ts +++ b/packages/plots/src/core/plots/sankey/index.ts @@ -10,7 +10,7 @@ export class Sankey extends Plot { public type = 'sankey'; /** - * 获取 双轴图 默认配置项 + * 获取 桑基图 默认配置项 * 供外部使用 */ static getDefaultOptions(): Partial { @@ -18,14 +18,14 @@ export class Sankey extends Plot { } /** - * 获取 条形图 默认配置 + * 获取 桑基图 默认配置 */ protected getDefaultOptions() { return Sankey.getDefaultOptions(); } /** - * 条形图适配器 + * 桑基图适配器 */ protected getSchemaAdaptor(): (params: Adaptor) => void { return adaptor; diff --git a/site/examples/statistics/sankey/demo/alipay.js b/site/examples/statistics/sankey/demo/alipay.js new file mode 100644 index 0000000000..8066a3f1ae --- /dev/null +++ b/site/examples/statistics/sankey/demo/alipay.js @@ -0,0 +1,50 @@ +import { Sankey } from '@ant-design/plots'; +import React from 'react'; +import ReactDOM from 'react-dom'; + +const colors = [ + '#5B8FF9', + '#61DDAA', + '#65789B', + '#F6BD16', + '#7262fd', + '#78D3F8', + '#9661BC', + '#F6903D', + '#008685', + '#F08BB4', +]; + +const data = [ + { source: '首次打开', target: '首页 UV', value: 160 }, + { source: '结果页', target: '首页 UV', value: 40 }, + { source: '验证页', target: '首页 UV', value: 10 }, + { source: '我的', target: '首页 UV', value: 10 }, + { source: '朋友', target: '首页 UV', value: 8 }, + { source: '其他来源', target: '首页 UV', value: 27 }, + { source: '首页 UV', target: '理财', value: 30 }, + { source: '首页 UV', target: '扫一扫', value: 40 }, + { source: '首页 UV', target: '服务', value: 35 }, + { source: '首页 UV', target: '蚂蚁森林', value: 25 }, + { source: '首页 UV', target: '跳失', value: 10 }, + { source: '首页 UV', target: '借呗', value: 30 }, + { source: '首页 UV', target: '花呗', value: 40 }, + { source: '首页 UV', target: '其他流向', value: 45 }, +]; + +const DemoSankey = () => { + const config = { + data, + scale: { color: { range: colors } }, + layout: { nodeWidth: 0.01 }, + linkColorField: (d) => d.source.key, + style: { + labelFontSize: 13, + linkFillOpacity: 0.4, + nodeStrokeWidth: 0, + }, + }; + return ; +}; + +ReactDOM.render(, document.getElementById('container')); diff --git a/site/examples/statistics/sankey/demo/basic.js b/site/examples/statistics/sankey/demo/basic.js index d224939334..898854cc92 100644 --- a/site/examples/statistics/sankey/demo/basic.js +++ b/site/examples/statistics/sankey/demo/basic.js @@ -4,18 +4,9 @@ import ReactDOM from 'react-dom'; const DemoSankey = () => { const config = { - layout: { nodeAlign: 'center', nodePadding: 0.03 }, data: { type: 'fetch', value: 'https://assets.antv.antgroup.com/g2/energy.json', - transform: [ - { - type: 'custom', - callback: (data) => ({ - links: data, - }), - }, - ], }, scale: { color: { @@ -33,6 +24,7 @@ const DemoSankey = () => { ], }, }, + layout: { nodeAlign: 'center', nodePadding: 0.03 }, style: { labelSpacing: 3, labelFontWeight: 'bold', diff --git a/site/examples/statistics/sankey/demo/energy.js b/site/examples/statistics/sankey/demo/energy.js new file mode 100644 index 0000000000..5f3441ee30 --- /dev/null +++ b/site/examples/statistics/sankey/demo/energy.js @@ -0,0 +1,19 @@ +import { Sankey } from '@ant-design/plots'; +import React from 'react'; +import ReactDOM from 'react-dom'; + +const DemoSankey = () => { + const config = { + data: { + type: 'fetch', + value: 'https://gw.alipayobjects.com/os/bmw-prod/fa3414cc-75ed-47b4-8306-f2ffe8c40127.json', + }, + scale: { color: { range: ['red', 'green', 'yellow'] } }, + layout: { nodeWidth: 0.01, nodePadding: 0.01 }, + linkColorField: (d) => d.source.key, + style: { linkFillOpacity: 0.4 }, + }; + return ; +}; + +ReactDOM.render(, document.getElementById('container')); diff --git a/site/examples/statistics/sankey/demo/meta.json b/site/examples/statistics/sankey/demo/meta.json index cf1ca51a71..ea33b3e699 100644 --- a/site/examples/statistics/sankey/demo/meta.json +++ b/site/examples/statistics/sankey/demo/meta.json @@ -11,6 +11,30 @@ "en": "Sankey" }, "screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*dACBR7ANcfEAAAAAAAAAAAAADmJ7AQ/original" + }, + { + "filename": "alipay.js", + "title": { + "zh": "支付宝流量桑基图", + "en": "Alipay sankey" + }, + "screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*fecqTpstXu0AAAAAAAAAAAAADmJ7AQ/original" + }, + { + "filename": "energy.js", + "title": { + "zh": "能量关系桑基图", + "en": "Energy sankey" + }, + "screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*8o1RQJ2fqdsAAAAAAAAAAAAADmJ7AQ/original" + }, + { + "filename": "node-sort-sankey.js", + "title": { + "zh": "节点排序前桑基图", + "en": "NodeSort sankey" + }, + "screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*Ubm3Q4E1qCAAAAAAAAAAAAAADmJ7AQ/original" } ] } diff --git a/site/examples/statistics/sankey/demo/node-sort-sankey.js b/site/examples/statistics/sankey/demo/node-sort-sankey.js new file mode 100644 index 0000000000..01728f98d9 --- /dev/null +++ b/site/examples/statistics/sankey/demo/node-sort-sankey.js @@ -0,0 +1,53 @@ +import { Sankey } from '@ant-design/plots'; +import React from 'react'; +import ReactDOM from 'react-dom'; + +const colors = [ + '#5B8FF9', + '#61DDAA', + '#65789B', + '#F6BD16', + '#7262fd', + '#78D3F8', + '#9661BC', + '#F6903D', + '#008685', + '#F08BB4', +]; + +const data = [ + { source: '首次打开', target: '首页 UV', value: 160 }, + { source: '结果页', target: '首页 UV', value: 40 }, + { source: '验证页', target: '首页 UV', value: 10 }, + { source: '我的', target: '首页 UV', value: 10 }, + { source: '朋友', target: '首页 UV', value: 8 }, + { source: '其他来源', target: '首页 UV', value: 27 }, + { source: '首页 UV', target: '理财', value: 30 }, + { source: '首页 UV', target: '扫一扫', value: 40 }, + { source: '首页 UV', target: '服务', value: 35 }, + { source: '首页 UV', target: '蚂蚁森林', value: 25 }, + { source: '首页 UV', target: '跳失', value: 10 }, + { source: '首页 UV', target: '借呗', value: 30 }, + { source: '首页 UV', target: '花呗', value: 40 }, + { source: '首页 UV', target: '其他流向', value: 45 }, +]; + +const DemoSankey = () => { + const config = { + data, + scale: { color: { range: colors } }, + layout: { + nodeWidth: 0.01, + nodeSort: (a, b) => b.value - a.value, + }, + linkColorField: (d) => d.source.key, + style: { + labelFontSize: 13, + linkFillOpacity: 0.4, + nodeStrokeWidth: 0, + }, + }; + return ; +}; + +ReactDOM.render(, document.getElementById('container'));