From b117bfd99d2baf7f29801104ffe86f94a562be07 Mon Sep 17 00:00:00 2001 From: Deturium Date: Wed, 13 Nov 2019 10:08:04 +0800 Subject: [PATCH 1/2] fix: BannerSVG --- site/pages/index.zh.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/site/pages/index.zh.tsx b/site/pages/index.zh.tsx index 6a3cc028f5..c2c6e327b6 100644 --- a/site/pages/index.zh.tsx +++ b/site/pages/index.zh.tsx @@ -10,7 +10,7 @@ import BannerSVG from '@antv/gatsby-theme-antv/site/components/BannerSVG'; const IndexPage = () => { const { t, i18n } = useTranslation(); - const coverImage = BannerSVG(); + const coverImage = ; const features = [ { @@ -141,4 +141,4 @@ const IndexPage = () => { ); }; -export default IndexPage; \ No newline at end of file +export default IndexPage; From 3b941df7ba8c94904efd86a72e64e63067359fe6 Mon Sep 17 00:00:00 2001 From: Deturium Date: Wed, 13 Nov 2019 10:10:12 +0800 Subject: [PATCH 2/2] docs: scatter demos --- examples/scatter/default/demo/default.js | 47 ++++++ examples/scatter/default/demo/meta.json | 13 ++ examples/scatter/default/index.zh.md | 6 + examples/scatter/hover/demo/hover.js | 163 +++++++++++++++++++ examples/scatter/hover/demo/meta.json | 13 ++ examples/scatter/hover/index.zh.md | 6 + examples/scatter/node/demo/meta.json | 13 ++ examples/scatter/node/demo/node.js | 179 +++++++++++++++++++++ examples/scatter/node/index.zh.md | 6 + examples/scatter/position/demo/meta.json | 13 ++ examples/scatter/position/demo/position.js | 57 +++++++ examples/scatter/position/index.zh.md | 6 + 12 files changed, 522 insertions(+) create mode 100644 examples/scatter/default/demo/default.js create mode 100644 examples/scatter/default/demo/meta.json create mode 100644 examples/scatter/default/index.zh.md create mode 100644 examples/scatter/hover/demo/hover.js create mode 100644 examples/scatter/hover/demo/meta.json create mode 100644 examples/scatter/hover/index.zh.md create mode 100644 examples/scatter/node/demo/meta.json create mode 100644 examples/scatter/node/demo/node.js create mode 100644 examples/scatter/node/index.zh.md create mode 100644 examples/scatter/position/demo/meta.json create mode 100644 examples/scatter/position/demo/position.js create mode 100644 examples/scatter/position/index.zh.md diff --git a/examples/scatter/default/demo/default.js b/examples/scatter/default/demo/default.js new file mode 100644 index 0000000000..633cf82811 --- /dev/null +++ b/examples/scatter/default/demo/default.js @@ -0,0 +1,47 @@ +import G6 from '@antv/g6'; + +const data = { + nodes: [{ + id: 'a', + x: 200, + y: 100, + style: { fill: '#F04864', stroke: null } + }, { + id: 'b', + x: 100, + y: 200, + style: { fill: '#FACC14', stroke: null } + }, { + id: 'c', + x: 300, + y: 200, + style: { fill: '#40a9ff', stroke: null } + }], + edges: [{ + id: 'a2b', + source: 'a', + target: 'b' + }, { + id: 'a2c', + source: 'a', + target: 'c' + }] +}; + +const graph = new G6.Graph({ + container: 'container', + width: 500, + height: 500, + animate: true +}); + +graph.data(data); +graph.render(); + +setInterval(() => { + data.nodes.forEach(node => { + node.x += Math.random() * 50 - 25; + node.y += Math.random() * 50 - 25; + }); + graph.changeData(data); +}, 600); diff --git a/examples/scatter/default/demo/meta.json b/examples/scatter/default/demo/meta.json new file mode 100644 index 0000000000..0894d87b59 --- /dev/null +++ b/examples/scatter/default/demo/meta.json @@ -0,0 +1,13 @@ +{ + "title": { + "zh": "中文分类", + "en": "Category" + }, + "demos": [ + { + "filename": "default.js", + "title": "默认动画", + "screenshot": "https://cdn.nlark.com/yuque/0/2019/gif/174835/1552996333072-ac3949af-c9ac-4351-9e06-8b4703127f7e.gif" + } + ] +} diff --git a/examples/scatter/default/index.zh.md b/examples/scatter/default/index.zh.md new file mode 100644 index 0000000000..b4be3c71f0 --- /dev/null +++ b/examples/scatter/default/index.zh.md @@ -0,0 +1,6 @@ +--- +title: 默认动画 +order: 0 +redirect_from: + - /zh/examples +--- diff --git a/examples/scatter/hover/demo/hover.js b/examples/scatter/hover/demo/hover.js new file mode 100644 index 0000000000..1a8f37d875 --- /dev/null +++ b/examples/scatter/hover/demo/hover.js @@ -0,0 +1,163 @@ +import G6 from '@antv/g6'; + +const nodes = []; +const edges = []; + +// 中心节点 +const centerNode = { + id: 'center', + x: 500, + y: 300, + shape: 'center-node', + size: 20 +}; +nodes.push(centerNode); +// 左侧添加 4 个节点 +for (let i = 0; i < 4; i++) { + const id = 'left' + i; + nodes.push({ + id, + x: 250, + y: (i + 1) * 100 + 50, + shape: 'leaf-node' + }); + edges.push({ source: id, target: 'center', shape: 'can-running' }); +} +// 右侧添加 6 个节点 +for (let i = 0; i < 6; i++) { + const id = 'right' + i; + nodes.push({ + id, + x: 750, + y: i * 100 + 50, + shape: 'leaf-node' + }); + edges.push({ source: 'center', target: id, shape: 'can-running' }); +} + +G6.registerNode('leaf-node', { + afterDraw(cfg, group) { + group.addShape('circle', { + attrs: { + x: 0, + y: 0, + r: 5, + fill: cfg.color || '#dee9ff' + } + }); + }, + getAnchorPoints() { + return [ + [ 0, 0.5 ], + [ 1, 0.5 ] + ]; + } +}, 'circle'); + +G6.registerNode('center-node', { + afterDraw(cfg, group) { + const r = cfg.size / 2; + group.addShape('circle', { + zIndex: -3, + attrs: { + x: 0, + y: 0, + r: r + 10, + fill: 'gray', + opacity: 0.4 + } + }); + group.addShape('circle', { + zIndex: -2, + attrs: { + x: 0, + y: 0, + r: r + 20, + fill: 'gray', + opacity: 0.2 + } + }); + group.sort(); + }, + getAnchorPoints() { + return [ + [ 0, 0.5 ], + [ 1, 0.5 ] + ]; + } +}, 'circle'); + +// lineDash 的差值,可以在后面提供 util 方法自动计算 +const dashArray = [ + [ 0, 1 ], + [ 0, 2 ], + [ 1, 2 ], + [ 0, 1, 1, 2 ], + [ 0, 2, 1, 2 ], + [ 1, 2, 1, 2 ], + [ 2, 2, 1, 2 ], + [ 3, 2, 1, 2 ], + [ 4, 2, 1, 2 ] +]; +const lineDash = [ 4, 2, 1, 2 ]; +const interval = 9; + +G6.registerEdge('can-running', { + setState(name, value, item) { + const shape = item.get('keyShape'); + if (name === 'running') { + if (value) { + const length = shape.getTotalLength(); // 后续 G 增加 totalLength 的接口 + let totalArray = []; + for (let i = 0; i < length; i += interval) { + totalArray = totalArray.concat(lineDash); + } + let index = 0; + shape.animate({ + onFrame() { + const cfg = { + lineDash: dashArray[index].concat(totalArray) + }; + index = (index + 1) % interval; + return cfg; + }, + repeat: true + }, 3000); + } else { + shape.stopAnimate(); + shape.attr('lineDash', null); + } + } + } +}, 'cubic-horizontal'); + +const graph = new G6.Graph({ + container: 'container', + width: 500, + height: 500, + defaultNode: { + style: { + fill: '#82affc' + } + }, + defaultEdge: { + style: { + stroke: '#b5b5b5' + } + } +}); +graph.data({ nodes, edges }); +graph.render(); +graph.fitView(); + +// 响应 hover 状态 +graph.on('node:mouseenter', ev => { + const node = ev.item; + const edges = node.getEdges(); + edges.forEach(edge => graph.setItemState(edge, 'running', true)); +}); +graph.on('node:mouseleave', ev => { + const node = ev.item; + const edges = node.getEdges(); + edges.forEach(edge => graph.setItemState(edge, 'running', false)); +}); diff --git a/examples/scatter/hover/demo/meta.json b/examples/scatter/hover/demo/meta.json new file mode 100644 index 0000000000..43bcc40ac7 --- /dev/null +++ b/examples/scatter/hover/demo/meta.json @@ -0,0 +1,13 @@ +{ + "title": { + "zh": "中文分类", + "en": "Category" + }, + "demos": [ + { + "filename": "hover.js", + "title": "状态切换", + "screenshot": "https://cdn.nlark.com/yuque/0/2019/gif/174835/1552996205932-45633abc-8ec1-4547-aa4d-fa55e1109cc6.gif" + } + ] +} diff --git a/examples/scatter/hover/index.zh.md b/examples/scatter/hover/index.zh.md new file mode 100644 index 0000000000..9c2f3dcace --- /dev/null +++ b/examples/scatter/hover/index.zh.md @@ -0,0 +1,6 @@ +--- +title: 状态切换 +order: 1 +redirect_from: + - /zh/examples +--- diff --git a/examples/scatter/node/demo/meta.json b/examples/scatter/node/demo/meta.json new file mode 100644 index 0000000000..4090e893c2 --- /dev/null +++ b/examples/scatter/node/demo/meta.json @@ -0,0 +1,13 @@ +{ + "title": { + "zh": "中文分类", + "en": "Category" + }, + "demos": [ + { + "filename": "node.js", + "title": "节点动画", + "screenshot": "https://cdn.nlark.com/yuque/0/2019/gif/174835/1552996271257-d5a8b333-ea97-4cb4-9a0e-400ec36db6c7.gif" + } + ] +} diff --git a/examples/scatter/node/demo/node.js b/examples/scatter/node/demo/node.js new file mode 100644 index 0000000000..6182ed5521 --- /dev/null +++ b/examples/scatter/node/demo/node.js @@ -0,0 +1,179 @@ +import G6 from '@antv/g6'; + +const Util = G6.Util; +const data = { + nodes: [{ + id: 'node1', + x: 100, + y: 100, + shape: 'circle-animate', + size: 20, + label: '图形动画', + labelCfg: { + position: 'top' + } + }, { + id: 'node2', + x: 300, + y: 200, + shape: 'background-animate', + color: '#40a9ff', + size: 20, + label: '背景动画', + labelCfg: { + position: 'left', + offset: 10 + } + }, { + id: 'node3', + x: 400, + y: 100, + size: [ 40, 40 ], + shape: 'inner-animate', + img: 'data:image/webp;base64,UklGRq4FAABXRUJQVlA4IKIFAABwHwCdASo8ADwAPiEMhEGhhv6rQAYAgS2NHsdCq/4D8AOoA64OEUAj/XPxVwyvRGvyO/gGxN/t3oK/1X6zesX3L/p/RP/2HCgKAB9AGeAbCB+AGwAbQBtA/8c/m/4PYHTonm+SzRH6B9sv2i/rOZC+G/ln9l/ML/GdoD7APcA/TD+09QDzAfrX+vHYM9AD+Uf0zrAPQA/bH0vv2t+CH9qf2R+A39e6X098/I7IAcLcs8Gjmc/9T7gPbX9H+wJ+rPVV9En9ZmBI5oUiYhkYHIVjRr9hzCTPcV5Rs/wjjIHkxPgtr/3ALZSuUm146HHwqQVA23hnnqH/4aJ/k4v4hU6RBZ0AAAD+//8ARPyL9yWIlAbWBAD0oKSqlYWreuRa3Oj02u+TvSQS8iwMYewUYTWLDNp9wOlFJaWnqE+za35UwUXuDAT6T0I4fwY+u+qrRVhl+S1ir4X7BQiNswug5AX+MjQcXEeUwfSIEUT+DFPCr+BUiwTbFxLni7fv61vRbmXoauLz4tiqOFTzEGP8tNXP5+H7mZVGfNjIxapT3FGUtqBdp/SD5cTOYOkn2fawkpqpCSqf2+CfiGWtIF673fEzlk/hIbWDhQ81C/ddxLn609d/5efckbdZ8HZbhhVmM82/Uat7CFmw1SH5xCxRxEEhjpf1EP1Xn5q9VZfm1+OFTab/MN67Xha8K//5oVBlMgZALE653X0fas/+2xMqiyCu5Wa7PHsCwbBwqROfNmzi4LPOTjkFPHVKDD1Nfj4/sul6cANdF68rf2jszlyZsUUoLTP7H3swSroc3ssNXSRVAcYd7+iBZpfoAYWvKgnr+Hv62fHZX5ZbjYbYzVjq6fsXkubto858NuUx4+ILb5y7dP6W3/IYVeUSF0yZseKIZhOMs9BBf5uB2Y3Ott//+1OG7hYINzcqigrzWAOJbSmVw3G0ULywkobx+rvfk8VmZFzQGgP/+4T74mp/vsZyM1NLguiTO2gNO05tcpXwveq5mrcweXrJ/bRZDmU2KBrnXhkXq+735c+UHTFq4h4jMOPm5shKioB6XaqhUf3DJlMg8937g/SKjrgD0H5sNm0/k4FfilBbcrsjc3dd6cwEYJo3CNhe3SpNJ2geNXyV4/hq/BZXZ1kiVknjmf5cUx7Tv/9Sb+fQ/DgAsRNSz1wiVodiLjP7aVrkxbWx5gJ8U/j0o1Ipm/nyDZRPrQXmbPAcy1eDDejxTDBKe42ElHpC2QlFdhOedsp4i9QVjt8EqWGy1YzPaGqZhCVg/LWt8/+4BmiCzNGtpR21MGJf4kI/n/1sbe36e1QBCBAx4EVfTM82ZM2lh0P189e7eY0A3NzXWVrUek8SEn+DYYCQeEaC5hDHGreFHT1baY6KyrFx3G9oMm3fLrCqmNjFRnZa3LB/5m8FgCpq9B/1OCLRE5GzVTZnVzj/4V38PgCIpX16Kznijf01+MkDeS9oCF2hEXQ9tr+mPLrjGy4Cg5fyLgyCj1fUq33nMf79Svli2h83m3gqkoxJcXvBetFQP8V/gRjBNGmFXK5TfwLhbolWEjDqUGK3n+hxzQLif9zreYO88EIRTUNbzE1/Sn7rBEtjB0uawNje5OubWsB62SOlMZoZpxrDbMb4UvQrODPhSafmhcYe9zm/dHxssMfUthhDKjyMhoRhngPjbzfGXmIV2Omgrn/zbefK/PawUGSH6x4Qk4HCN4/X8S+XCf51JJtOQeHST/yfwg69uMkE07SONnhGUrL6j5oQn6JI+zkaH/H/P/Ti/pfOTfAWxQNiMvWX08mqbuUweFSQ/G5YUP/uCvZAXutf1+Nhl2jj/n4/fPOihPjwvfFnnjOaQvs9PSpF33d+396LASZ3IID/4UP4pf9eOMXw82ccoUUUHX6MfBWyBDvARCrdPmerUwKwW+lBIAe1dsAAAA==', + label: '图片动画', + labelCfg: { + position: 'right' + } + }, { + id: 'node4', + x: 300, + y: 300, + shape: 'rect', + label: '无动画', + labelCfg: { + position: 'bottom' + } + }], + edges: [{ + source: 'node1', + target: 'node2' + }, + { + source: 'node3', + target: 'node2' + }, + { + source: 'node2', + target: 'node4' + } + ] +}; + +// 缩放动画 +G6.registerNode('circle-animate', { + afterDraw(cfg, group) { + const shape = group.get('children')[0]; + shape.animate({ + repeat: true, + onFrame(ratio) { + const diff = ratio <= 0.5 ? ratio * 10 : (1 - ratio) * 10; + return { + r: cfg.size / 2 + diff + }; + } + }, 3000, 'easeCubic'); + } +}, 'circle'); + +// 背景动画 +G6.registerNode('background-animate', { + afterDraw(cfg, group) { + const r = cfg.size / 2; + const back1 = group.addShape('circle', { + zIndex: -3, + attrs: { + x: 0, + y: 0, + r, + fill: cfg.color, + opacity: 0.6 + } + }); + const back2 = group.addShape('circle', { + zIndex: -2, + attrs: { + x: 0, + y: 0, + r, + fill: cfg.color, + opacity: 0.6 + } + }); + const back3 = group.addShape('circle', { + zIndex: -1, + attrs: { + x: 0, + y: 0, + r, + fill: cfg.color, + opacity: 0.6 + } + }); + group.sort(); // 排序,根据 zIndex 排序 + back1.animate({ // 逐渐放大,并消失 + r: r + 10, + opacity: 0.1, + repeat: true // 循环 + }, 3000, 'easeCubic', null, 0); // 无延迟 + back2.animate({ // 逐渐放大,并消失 + r: r + 10, + opacity: 0.1, + repeat: true // 循环 + }, 3000, 'easeCubic', null, 1000); // 1 秒延迟 + back3.animate({ // 逐渐放大,并消失 + r: r + 10, + opacity: 0.1, + repeat: true // 循环 + }, 3000, 'easeCubic', null, 2000); // 2 秒延迟 + } +}, 'circle'); + +// 图片动画 +G6.registerNode('inner-animate', { + afterDraw(cfg, group) { + const size = cfg.size; + const width = size[0] - 12; + const height = size[1] - 12; + const image = group.addShape('image', { + attrs: { + x: -width / 2, + y: -height / 2, + width, + height, + img: cfg.img + } + }); + image.animate({ + onFrame(ratio) { + const matrix = Util.mat3.create(); + const toMatrix = Util.transform(matrix, [ + [ 'r', ratio * Math.PI * 2 ] + ]); + return { + matrix: toMatrix + }; + }, + repeat: true + }, 3000, 'easeCubic'); + } +}, 'rect'); + +const graph = new G6.Graph({ + container: 'container', + width: 500, + height: 500, + defaultNode: { + style: { + fill: '#82affc' + } + }, + defaultEdge: { + style: { + lineWidth: 1, + stroke: '#b5b5b5' + } + } +}); +graph.data(data); +graph.render(); diff --git a/examples/scatter/node/index.zh.md b/examples/scatter/node/index.zh.md new file mode 100644 index 0000000000..baaacc875d --- /dev/null +++ b/examples/scatter/node/index.zh.md @@ -0,0 +1,6 @@ +--- +title: 节点动画 +order: 2 +redirect_from: + - /zh/examples +--- diff --git a/examples/scatter/position/demo/meta.json b/examples/scatter/position/demo/meta.json new file mode 100644 index 0000000000..bd711e8613 --- /dev/null +++ b/examples/scatter/position/demo/meta.json @@ -0,0 +1,13 @@ +{ + "title": { + "zh": "中文分类", + "en": "Category" + }, + "demos": [ + { + "filename": "position.js", + "title": "自定义动画", + "screenshot": "https://cdn.nlark.com/yuque/0/2019/gif/174835/1552996388492-f63d0b8e-8ff6-4136-9531-33f4a98f07a6.gif" + } + ] +} diff --git a/examples/scatter/position/demo/position.js b/examples/scatter/position/demo/position.js new file mode 100644 index 0000000000..6d6ac8aee3 --- /dev/null +++ b/examples/scatter/position/demo/position.js @@ -0,0 +1,57 @@ +import G6 from '@antv/g6'; + +const r = 50; +const radius = Math.PI; + +const graph = new G6.Graph({ + container: 'container', + width: 500, + height: 500, + animate: true, + animateCfg: { + duration: 1000, + onFrame(node, ratio, toAttrs, fromAttrs) { + const current = radius * ratio; + let x = fromAttrs.x; + let y = fromAttrs.y; + if (fromAttrs.x > toAttrs.x) { + x = x - r + r * Math.cos(current); + y += r * Math.sin(current); + } else { + x = x + r - r * Math.cos(current); + y -= r * Math.sin(current); + } + return { x, y }; + } + } +}); + +// 加入两个节点 +const node1 = graph.addItem('node', { + id: 'node1', + x: 100, + y: 100, + shape: 'circle', + style: { fill: '#F04864', lineWidth: 0 } +}); +const node2 = graph.addItem('node', { + id: 'node2', + x: 200, + y: 100, + shape: 'circle', + style: { fill: '#40a9ff', lineWidth: 0 } +}); + +// 循环动画 +let count = 0; +setInterval(() => { + if (count % 2 === 0) { + node1.get('model').x = 200; + node2.get('model').x = 100; + } else { + node1.get('model').x = 100; + node2.get('model').x = 200; + } + count++; + graph.refresh(); +}, 1000); diff --git a/examples/scatter/position/index.zh.md b/examples/scatter/position/index.zh.md new file mode 100644 index 0000000000..ebb3640091 --- /dev/null +++ b/examples/scatter/position/index.zh.md @@ -0,0 +1,6 @@ +--- +title: 自定义动画 +order: 3 +redirect_from: + - /zh/examples +---