From f35975e5406318387c147dacfb171d1ba77d8f51 Mon Sep 17 00:00:00 2001 From: baizn <576375879@qq.com> Date: Wed, 18 Mar 2020 14:00:54 +0800 Subject: [PATCH 1/6] feat: support hiding non-keyshape elements when scaling canvas --- package.json | 2 +- src/behavior/zoom-canvas.ts | 56 +++++++++++++++++++++++- src/interface/graph.ts | 2 + tests/unit/behavior/zoom-spec.ts | 73 ++++++++++++++++++++++++++++++++ 4 files changed, 131 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index af2c84053bf..5a1ae46d9f8 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "site:deploy": "npm run site:build && gh-pages -d public", "start": "npm run site:develop", "test": "jest", - "test-live": "DEBUG_MODE=1 jest --watch ./tests/unit/layout/dagre-spec.ts", + "test-live": "DEBUG_MODE=1 jest --watch ./tests/unit/behavior/zoom-spec.ts", "lint-staged:js": "eslint --ext .js,.jsx,.ts,.tsx", "watch": "father build -w", "cdn": "antv-bin upload -n @antv/g6" diff --git a/src/behavior/zoom-canvas.ts b/src/behavior/zoom-canvas.ts index 0c8324f431b..fae05e0ad8a 100644 --- a/src/behavior/zoom-canvas.ts +++ b/src/behavior/zoom-canvas.ts @@ -6,8 +6,10 @@ export default { getDefaultCfg(): object { return { sensitivity: 2, - minZoom: 0.1, + minZoom: 0.2, maxZoom: 10, + enableOptimize: false, + optimizeZoom: 0.7 }; }, getEvents(): { [key in G6Event]?: string } { @@ -35,6 +37,58 @@ export default { if (zoom > this.get('maxZoom') || zoom < this.get('minZoom')) { return; } + + const enableOptimize = this.get('enableOptimize') + if(enableOptimize) { + const optimizeZoom = this.get('optimizeZoom') + + const currentZoom = graph.getZoom() + console.log(currentZoom) + if(currentZoom < optimizeZoom) { + const nodes = graph.getNodes() + const edges = graph.getEdges() + nodes.map(node => { + if(!node.destroyed) { + const children = node.getContainer().get('children') + children.map(shape => { + if(!shape.destoryed && !shape.get('isKeyShape')) { + shape.hide() + } + }) + } + }) + + edges.map(edge => { + const children = edge.getContainer().get('children') + children.map(shape => { + if(!shape.get('isKeyShape')) { + shape.hide() + } + }) + }) + } else { + const nodes = graph.getNodes() + const edges = graph.getEdges() + nodes.map(node => { + const children = node.getContainer().get('children') + children.map(shape => { + if(!shape.get('visible')) { + shape.show() + } + }) + }) + + edges.map(edge => { + const children = edge.getContainer().get('children') + children.map(shape => { + if(!shape.get('visible')) { + shape.show() + } + }) + }) + } + } + graph.zoom(ratio, { x: point.x, y: point.y }); graph.emit('wheelzoom', e); }, diff --git a/src/interface/graph.ts b/src/interface/graph.ts index 8c870bd6291..8e5a2244c36 100644 --- a/src/interface/graph.ts +++ b/src/interface/graph.ts @@ -27,6 +27,8 @@ export interface IModeOption { enableDelegate?: boolean; maxZoom?: number; minZoom?: number; + enableOptimize?: boolean; + optimizeZoom?: number; multiple?: boolean; selectedState?: string; includeEdges?: boolean; diff --git a/tests/unit/behavior/zoom-spec.ts b/tests/unit/behavior/zoom-spec.ts index 318f4d63312..8179f938127 100644 --- a/tests/unit/behavior/zoom-spec.ts +++ b/tests/unit/behavior/zoom-spec.ts @@ -124,4 +124,77 @@ describe('zoom-canvas', () => { expect(matrix[6]).toEqual(10); expect(matrix[7]).toEqual(10); }); + + it.only('zoom with optimize', () => { + const graph = new Graph({ + container: div, + width: 500, + height: 500, + modes: { + default: [{ + type: 'zoom-canvas', + enableOptimize: true + }] + }, + }); + + let e = createWheelEvent(graph.get('canvas').get('el'), 100, 100, 100); + graph.emit('wheel', e); + let matrix = graph.get('group').getMatrix(); + console.log(matrix) + expect(approximateEqual(matrix[0], 1.1)).toBe(true); + expect(approximateEqual(matrix[4], 1.1)).toBe(true); + expect(approximateEqual(matrix[6], -10)).toBe(true); + expect(approximateEqual(matrix[7], -10)).toBe(true); + + const data = { + nodes: [ + { + id: 'node1', + x: 100, + y: 100, + label: 'label' + }, + { + id: 'node2', + x: 100, + y: 200, + label: 'label2' + } + ], + edges: [ + { + source: 'node1', + target: 'node2', + label: 'edge' + } + ] + } + + graph.data(data) + graph.render() + + // 默认 zoom=1,会显示所有元素 + let node1 = graph.findById('node1') + let container = node1.getContainer() + container.get('children').map(child => { + expect(child.get('visible')).toBe(true) + }) + + graph.zoom(0.5) + e = createWheelEvent(graph.get('canvas').get('el'), 100, 100, 100); + graph.emit('wheel', e); + + // 只显示 keyShape + node1 = graph.findById('node1') + container = node1.getContainer() + expect(node1.getKeyShape().get('visible')).toBe(true) + container.get('children').map(child => { + if(!child.get('isKeyShape')) { + expect(child.get('visible')).toBe(false) + } + }) + + graph.destroy() + }) }); From b51b68952e0369263f459f64392e213f79b054dc Mon Sep 17 00:00:00 2001 From: baizn <576375879@qq.com> Date: Wed, 18 Mar 2020 17:49:48 +0800 Subject: [PATCH 2/6] feat: support hiding non-keyshape elements when scaling canvas --- src/item/item.ts | 1 + stories/Issues/changeData/data.js | 90 ++++++++++++++++++++ stories/Issues/changeData/index.tsx | 123 ++++++++++++++++++++++++++++ stories/Issues/issues.stories.tsx | 6 +- tests/unit/behavior/zoom-spec.ts | 2 +- tests/unit/graph/graph-spec.ts | 2 +- 6 files changed, 221 insertions(+), 3 deletions(-) create mode 100644 stories/Issues/changeData/data.js create mode 100644 stories/Issues/changeData/index.tsx diff --git a/src/item/item.ts b/src/item/item.ts index 3be3290e8a4..9e786598f3d 100644 --- a/src/item/item.ts +++ b/src/item/item.ts @@ -83,6 +83,7 @@ export default class ItemBase implements IItemBase { if (!id) { id = uniqueId(this.get('type')); + this.get('model').id = id } this.set('id', id); diff --git a/stories/Issues/changeData/data.js b/stories/Issues/changeData/data.js new file mode 100644 index 00000000000..178b881c629 --- /dev/null +++ b/stories/Issues/changeData/data.js @@ -0,0 +1,90 @@ +export const data = { + nodes: [ + { + id: "9RQmLGueOikkikLvHVO", + label: "Mysql连接账户" + }, + { + id: "k79zNA0TkCwQPQWw4yn", + label: "ETL数据流" + }, + { + id: "GWMF0chbHRKDkENg1hS", + label: "ETL数据流2" + }, + { + id: "xCzXirgILRm9fF7gjeb", + label: "报告" + }, + { + id: "I2Msu7qhDMQPmGLOduP", + label: "Mysql数据源" + }, + { + id: "QUCo43VpL9LaPT4QVx0", + label: "Excel数据源" + }, + { + id: "GxZeEGkky88xKxq1r22", + label: "工厂输出表" + }, + { + id: "AoJc4qPcWeOL7NJwOh6", + label: "加工输出表" + }, + { + id: "cd_638e7750847a4cc78f3cd", + label: "图表1" + }, + { + id: "cd_8119cb085435454180558", + label: "图表2" + }, + { + id: "AKl8iaVQamqiMaMCF7E", + label: "csv数据源" + } + ], + edges: [ + { + source: "9RQmLGueOikkikLvHVO", + target: "I2Msu7qhDMQPmGLOduP" + }, + { + source: "k79zNA0TkCwQPQWw4yn", + target: "GxZeEGkky88xKxq1r22" + }, + { + source: "I2Msu7qhDMQPmGLOduP", + target: "k79zNA0TkCwQPQWw4yn" + }, + { + source: "QUCo43VpL9LaPT4QVx0", + target: "k79zNA0TkCwQPQWw4yn" + }, + { + source: "GxZeEGkky88xKxq1r22", + target: "xCzXirgILRm9fF7gjeb" + }, + { + source: "xCzXirgILRm9fF7gjeb", + target: "cd_638e7750847a4cc78f3cd" + }, + { + source: "xCzXirgILRm9fF7gjeb", + target: "cd_8119cb085435454180558" + }, + { + source: "AKl8iaVQamqiMaMCF7E", + target: "xCzXirgILRm9fF7gjeb" + }, + { + source: "GxZeEGkky88xKxq1r22", + target: "GWMF0chbHRKDkENg1hS" + }, + { + source: "GWMF0chbHRKDkENg1hS", + target: "AoJc4qPcWeOL7NJwOh6" + } + ] +}; diff --git a/stories/Issues/changeData/index.tsx b/stories/Issues/changeData/index.tsx new file mode 100644 index 00000000000..4f8b98720d7 --- /dev/null +++ b/stories/Issues/changeData/index.tsx @@ -0,0 +1,123 @@ +import React, { useRef, useEffect } from "react"; +import ReactDOM from "react-dom"; +import { mergeWith } from "lodash"; +import G6 from '../../../src'; +import isArray from "@antv/util/lib/is-array"; +import { data } from "./data"; +// import "./styles.css"; + +/** + * 【问题】!!! + * 当我点击“隐藏节点”后,节点正常隐藏 + * 但是点击“改变数据”调用changeData方法后,节点能隐藏,但是边又显示出来了。 + */ +export default () => { + const graphContainer = useRef(null); + let graph = useRef(null); + + // 图初始化 + useEffect(() => { + if (!graph.current) { + graph.current = new G6.Graph({ + container: graphContainer.current, + width: 1580, + height: 1080, + defaultNode: { + type: "circle", + size: 50, + anchorPoints: [[0, 0.5], [1, 0.5]] + }, + defaultEdge: { + type: "cubic-horizontal" + }, + layout: { + type: "dagre", + rankdir: "LR", + controlPoints: true + }, + modes: { + default: [ + "drag-canvas", + { + type: "zoom-canvas", + minZoom: 0.5, + maxZoom: 2 + } + ] + }, + animate: true + }); + } + + graph.current && graph.current.data(data); + graph.current && graph.current.render(); + }, []); + + /** + * 手动合并数据,达到异步加载的效果 + * @param {*} data 后端返回的新数据 + */ + const handleChangeData = data => { + const prevData = graph.current && graph.current.save(); + const newData = mergeWith(prevData, data, (objValue, srcValue) => { + if (isArray(objValue)) { + return objValue.concat(srcValue); + } + }); + + graph.current && graph.current.changeData(newData); + }; + + /** + * 模拟点击加载数据 + * 模拟点击AoJc4qPcWeOL7NJwOh6[加工输出表]节点后,后端返回异步加载的数据 + */ + const handleLoadData = () => { + const mockData = { + nodes: [ + { + id: "vm1234", + label: "新增报告" + } + ], + edges: [ + { + source: "AoJc4qPcWeOL7NJwOh6", + target: "vm1234" + } + ] + }; + handleChangeData(mockData); + }; + + /** + * 递归隐藏节点和边 + */ + const collapsePrev = node => { + const edges = node.getInEdges(); + edges.forEach(edge => { + edge.hide(); + const sourceNode = edge.getSource(); + if (sourceNode.getOutEdges().length === 1) { + sourceNode.hide(); + collapsePrev(sourceNode); + } + }); + }; + + /** + * 模拟折叠GxZeEGkky88xKxq1r22[工厂输出表]节点 + */ + const handleHideNode = () => { + const node = graph.current.findById("GxZeEGkky88xKxq1r22"); + collapsePrev(node); + }; + + return ( +
+ + +
+
+ ); +}; diff --git a/stories/Issues/issues.stories.tsx b/stories/Issues/issues.stories.tsx index 9a6caf1b794..6fa2632cb7a 100644 --- a/stories/Issues/issues.stories.tsx +++ b/stories/Issues/issues.stories.tsx @@ -2,6 +2,7 @@ import { storiesOf } from '@storybook/react'; import React from 'react'; import DragCanvas from './component/drag-canvas'; import DagreArrow from './component/dagre-arrow'; +import ChageData from './changeData' export default { title: 'Issues' }; @@ -11,4 +12,7 @@ storiesOf('Issues', module) )) .add('dagre polyline arrow', () => ( -)); +)) +.add('change data', () => ( + +)) diff --git a/tests/unit/behavior/zoom-spec.ts b/tests/unit/behavior/zoom-spec.ts index 8179f938127..f2890d820c2 100644 --- a/tests/unit/behavior/zoom-spec.ts +++ b/tests/unit/behavior/zoom-spec.ts @@ -125,7 +125,7 @@ describe('zoom-canvas', () => { expect(matrix[7]).toEqual(10); }); - it.only('zoom with optimize', () => { + it('zoom with optimize', () => { const graph = new Graph({ container: div, width: 500, diff --git a/tests/unit/graph/graph-spec.ts b/tests/unit/graph/graph-spec.ts index d26f6822d65..6e12a0e0db6 100644 --- a/tests/unit/graph/graph-spec.ts +++ b/tests/unit/graph/graph-spec.ts @@ -837,7 +837,7 @@ describe('all node link center', () => { expect(graph.findAllByState('node', 'b').length).toBe(0); }); - it.only('default node & edge style', () => { + it('default node & edge style', () => { const defaultGraph = new Graph({ container: div, width: 500, From d4222c1e2719459f50fe2c0eff1e8e83ca52c007 Mon Sep 17 00:00:00 2001 From: baizn <576375879@qq.com> Date: Thu, 19 Mar 2020 15:44:36 +0800 Subject: [PATCH 3/6] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=9B=B4=E6=8E=A5?= =?UTF-8?q?=E4=BD=BF=E7=94=A8attr=E4=BF=AE=E6=94=B9=E6=96=87=E6=9C=AC?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/shape/shapeBase.ts | 8 +- stories/Issues/attrs/index.tsx | 195 ++++++++++++++++++++++++++++++ stories/Issues/issues.stories.tsx | 4 + 3 files changed, 203 insertions(+), 4 deletions(-) create mode 100644 stories/Issues/attrs/index.tsx diff --git a/src/shape/shapeBase.ts b/src/shape/shapeBase.ts index 125aa60a48e..46a05c94bca 100644 --- a/src/shape/shapeBase.ts +++ b/src/shape/shapeBase.ts @@ -324,17 +324,17 @@ export const shapeBase: ShapeOptions = { const originstyles = {} deepMix(originstyles, originStyle, filtetDisableStatesStyle, enableStatesStyle) - for(const key in originstyles) { - const style = originstyles[key] + for(const originKey in originstyles) { + const style = originstyles[originKey] if(isPlainObject(style)) { - const subShape = group.find(element => element.get('name') === key) + const subShape = group.find(element => element.get('name') === originKey) if(subShape) { subShape.attr(style) } } else { // 非纯对象,则认为是设置到 keyShape 上面的 shape.attr({ - [key]: style + [originKey]: style }) } } diff --git a/stories/Issues/attrs/index.tsx b/stories/Issues/attrs/index.tsx new file mode 100644 index 00000000000..d7ae7654c68 --- /dev/null +++ b/stories/Issues/attrs/index.tsx @@ -0,0 +1,195 @@ + +import React, { useRef, useEffect } from "react"; +import G6 from '../../../src'; +// import "./styles.css"; + +// G6.Global.nodeStateStyle.selected = { +// stroke: "#d9d9d9", +// fill: "#5394ef" +// }; + +G6.registerNode( + "sql", + { + drawShape(cfg, group) { + const rect = group.addShape("rect", { + attrs: { + x: -75, + y: -25, + width: 168, + height: 36, + stroke: "#b4afaf", //'#303747', + fill: "#b4afaf", //'#303747', + lineWidth: 3, + radius: [5, 0, 0, 5] + }, + name: "rect-shape" + }); + if (cfg.name) { + group.addShape("text", { + attrs: { + text: cfg.name, + x: 0, + y: 0, + fill: "white", + fontSize: 14, + textAlign: "center", + //textBaseline: 'middle', + fontWeight: "bold" + }, + name: "text-shape" + }); + } + group.addShape("rect", { + attrs: { + x: 90, + y: -25, + width: 36, + height: 36, + stroke: "#0296EA", //'#303747', + fill: "#0296EA", //'#303747', + lineWidth: 3, + radius: [0, 5, 5, 0] + }, + name: "rect-shape-icon" + }); + group.addShape("rect", { + attrs: { + x: 98, + y: -18, + height: 20, + width: 20, + stroke: "white", //'#303747', + fill: "#0296EA", //'#303747', + radius: 2 + }, + name: "node-state-icon" + }); + group.addShape("text", { + attrs: { + text: cfg.stateIcon, + x: 108, + y: 0, + fill: "white", + fontSize: 14, + textAlign: "center", + fontWeight: "bold" + }, + name: "icon-text-shape" + }); + return rect; + } + }, + "single-node" +); + +export default () => { + const graphContainer = useRef(null); + let graph = null + + // 图初始化 + useEffect(() => { + if (!graph) { + graph = new G6.Graph({ + container: graphContainer.current, + width: 500, + height: 500, + renderer: "svg", + layout: { + type: "dagre", + nodesepFunc: d => { + if (d.id === "3") { + return 70; + } + return 70; + }, + ranksep: 30 + }, + defaultNode: { + type: "sql", + anchorPoints: [[0.5, 0], [0.5, 1]], + stateIcon: "+" // 节点中表示状态的icon配置 + }, + + defaultEdge: { + type: "cubic-vertical", + style: { + radius: 20, + offset: 45, + endArrow: true, + lineWidth: 2, + stroke: "#C2C8D5" + } + }, + modes: { + default: ["drag-canvas", "zoom-canvas", "click-select"] + }, + fitView: true + }); + } + + + const data = { + nodes: [ + { + id: "2", + dataType: "alps", + name: "alps_file2", + conf: [ + { + label: "conf", + value: "pai_graph.conf" + }, + { + label: "dot", + value: "pai_graph.dot" + }, + { + label: "init", + value: "init.rc" + } + ] + } + ] + }; + + graph.data(data); + graph.render(); + + graph.on('node:click', evt => { + let node = evt.item; + var child = node.get('group').find(function(item) { + return item.get("name") === "icon-text-shape"; //找到图标节点 + }); + if(child.attr('text') === '+') { + graph.updateItem(node, { + style: { + 'icon-text-shape': { + text: '-' + } + } + }) + } else { + graph.updateItem(node, { + style: { + 'icon-text-shape': { + text: '+' + } + } + }) + } + + + + + console.log('update text', child.attr('text')) + }) + }, []); + + + return ( +
+
+
+ ); +}; diff --git a/stories/Issues/issues.stories.tsx b/stories/Issues/issues.stories.tsx index 6fa2632cb7a..d7a05637fe7 100644 --- a/stories/Issues/issues.stories.tsx +++ b/stories/Issues/issues.stories.tsx @@ -3,6 +3,7 @@ import React from 'react'; import DragCanvas from './component/drag-canvas'; import DagreArrow from './component/dagre-arrow'; import ChageData from './changeData' +import ChangeAttr from './attrs' export default { title: 'Issues' }; @@ -16,3 +17,6 @@ storiesOf('Issues', module) .add('change data', () => ( )) +.add('change attr', () => ( + +)) From 1de31bba4a594d883b2aacb85fbe2bda776f2d32 Mon Sep 17 00:00:00 2001 From: baizn <576375879@qq.com> Date: Thu, 19 Mar 2020 16:58:20 +0800 Subject: [PATCH 4/6] fix: getStateStyle & clearItemStates --- CHANGELOG.md | 5 ++ docs/api/Graph.en.md | 2 +- docs/api/Graph.zh.md | 15 +++-- package.json | 4 +- src/global.ts | 2 +- src/item/item.ts | 4 +- tests/unit/graph/graph-spec.ts | 4 +- .../unit/state/update-element-states-spec.ts | 58 +++++++++++++++++++ 8 files changed, 80 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a154c2db96..903dd641434 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,9 @@ # ChangeLog +#### 3.4.2 +- feat: zoom-canvas behavior support hiding non-keyshape elements when scaling canvas; +- refactor: when sceond params is null, clearItemStates will clear all states of the item; +- fix: (changeData bug)[https://github.com/antvis/G6/issues/1323]; + #### 3.4.1 - feat: force layout clone original data model to allow the customized properties; - fix: BehaviorOptions type error; diff --git a/docs/api/Graph.en.md b/docs/api/Graph.en.md index f0aaf0cd8a8..a778d178685 100644 --- a/docs/api/Graph.en.md +++ b/docs/api/Graph.en.md @@ -645,7 +645,7 @@ Clear the states of the item. This function could clear multiple states in the s | Name | Type | Required | Description | | ------ | --------------- | -------- | ----------------------------------- | | item | String / Object | true | The id or the instance of the item. | -| states | String / Array | null  | false | It can be a single state value, an array, or null. When it is null, this operation will clear the **first** state of the item. | +| states | String / Array | null  | false | It can be a single state value, an array, or null. When it is null, this operation will clear all state of the item. | **Usage** diff --git a/docs/api/Graph.zh.md b/docs/api/Graph.zh.md index 6f6097f1776..39b0b84b9f2 100644 --- a/docs/api/Graph.zh.md +++ b/docs/api/Graph.zh.md @@ -628,24 +628,27 @@ graph.hideItem(item); graph.hideItem('nodeId'); ``` -### setItemState(item, state, enabled) +### setItemState(item, state, value) 设置元素状态。 +支持单个状态多值的情况,详情参考 [G6 状态管理最佳实践](https://g6.antv.vision/zh/docs/manual/middle/states/state-new)。 该方法在执行过程中会触发 `beforitemstatechange`,`afteritemstatechange` 事件。 **参数** | 名称 | 类型 | 是否必选 | 描述 | -| ------- | --------------- | -------- | ---------------------------------------------------- | -| item | String / Object | true | 元素 ID 或元素实例 | +| ------- | --------------- | -------- | ----------- | +| item | String / Item | true | 元素 ID 或元素实例 | | state | String | true | 状态值,支持自定义,如 selected、hover、actived 等。 | -| enabled | Boolean | true | 是否启用状态 | +| value | Boolean / String | true | 是否启用状态 | **用法** ```javascript graph.setItemState('node1', 'selected', true); + +graph.setItemState('node1', 'body', 'health'); ``` ### clearItemStates(item, states) @@ -657,7 +660,7 @@ graph.setItemState('node1', 'selected', true); | 名称 | 类型 | 是否必选 | 描述 | | ------ | --------------- | -------- | ------------------ | | item | String / Object | true | 元素 ID 或元素实例 | -| states | String / Array | null  | false | 取值可以是单个状态值,也可以是状态值数组或 `null`,当为 `null` 时,清除该元素的**第一个**状态。 | +| states | String / Array | null | false | 取值可以是单个状态值,也可以是状态值数组 | **用法** @@ -668,7 +671,7 @@ graph.clearItemStates(node, 'a'); // 清除多个状态 graph.clearItemStates(node, ['a', 'b']); -// 清除所有状态 +// 清除所有 graph.clearItemStates(node); ``` diff --git a/package.json b/package.json index 5a1ae46d9f8..54b1c58191e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g6", - "version": "3.4.1", + "version": "3.4.2", "description": "A Graph Visualization Framework in JavaScript", "keywords": [ "antv", @@ -50,7 +50,7 @@ "site:deploy": "npm run site:build && gh-pages -d public", "start": "npm run site:develop", "test": "jest", - "test-live": "DEBUG_MODE=1 jest --watch ./tests/unit/behavior/zoom-spec.ts", + "test-live": "DEBUG_MODE=1 jest --watch ./tests/unit/state/update-element-states-spec.ts", "lint-staged:js": "eslint --ext .js,.jsx,.ts,.tsx", "watch": "father build -w", "cdn": "antv-bin upload -n @antv/g6" diff --git a/src/global.ts b/src/global.ts index ecc8f62ac13..73f58d4c0a4 100644 --- a/src/global.ts +++ b/src/global.ts @@ -1,5 +1,5 @@ export default { - version: '3.4.1', + version: '3.4.2', rootContainerClassName: 'root-container', nodeContainerClassName: 'node-container', edgeContainerClassName: 'edge-container', diff --git a/src/item/item.ts b/src/item/item.ts index 9e786598f3d..f4fb4001e09 100644 --- a/src/item/item.ts +++ b/src/item/item.ts @@ -376,9 +376,9 @@ export default class ItemBase implements IItemBase { const model: ModelConfig = self.get('model'); const shape = model.shape || model.type; if (!states) { - console.warn(`clearItemStates 参数为空,则不清除任何状态`) - return; + states = originStates } + if (isString(states)) { states = [states]; } diff --git a/tests/unit/graph/graph-spec.ts b/tests/unit/graph/graph-spec.ts index 6e12a0e0db6..b25f344ca38 100644 --- a/tests/unit/graph/graph-spec.ts +++ b/tests/unit/graph/graph-spec.ts @@ -1158,9 +1158,9 @@ describe('mapper fn', () => { graph.setItemState(node, 'custom', true); expect(keyShape.attr('green')); + // clear all states of the item graph.clearItemStates(node); - // green - expect(keyShape.attr('fill')).toEqual('green'); + expect(keyShape.attr('fill')).toEqual('#666'); const edge = graph.addItem('edge', { id: 'edge2', source: 'node', target: 'node2Mapped' }); diff --git a/tests/unit/state/update-element-states-spec.ts b/tests/unit/state/update-element-states-spec.ts index 24f6cdc5d76..27f8c18044f 100644 --- a/tests/unit/state/update-element-states-spec.ts +++ b/tests/unit/state/update-element-states-spec.ts @@ -54,6 +54,64 @@ G6.registerNode('self-node', { describe('update', () => { + it('without second params, clear all states', () => { + const graph = new G6.Graph({ + container: div, + width: 500, + height: 500, + nodeStateStyles: { + hover: { + opacity: 0.3 + }, + 'body:health': { + fill: 'red' + } + }, + defaultNode: { + size: 25, + style: { + fill: 'steelblue', + opacity: 1 + } + }, + }); + const data = { + nodes: [ + { + id: 'node1', + x: 100, + y: 100, + }, + { + id: 'node2', + x: 200, + y: 100, + }, + ], + }; + graph.data(data); + graph.render(); + + const item = graph.findById('node1') + graph.setItemState(item, 'hover', true) + expect(item.hasState('hover')).toBe(true) + + const keyShape = item.getKeyShape() + expect(keyShape.attr('fill')).toEqual('steelblue') + + graph.setItemState(item, 'body', 'health') + + expect(item.getStates().length).toBe(2) + expect(item.hasState('body:health')).toBe(true) + expect(item.getKeyShape().attr('fill')).toEqual('red') + + graph.clearItemStates(item) + expect(item.hasState('hover')).toBe(false) + expect(item.hasState('body:health')).toBe(false) + expect(item.getStates().length).toBe(0) + + graph.destroy() + }) it('setItemState, then updateItem', () => { const graph = new G6.Graph({ container: div, From 19c487b04a79d58bf0bedfaca4b13a9902232ea3 Mon Sep 17 00:00:00 2001 From: baizn <576375879@qq.com> Date: Thu, 19 Mar 2020 19:01:48 +0800 Subject: [PATCH 5/6] fix: update behavior docs --- docs/manual/middle/states/defaultBehavior.zh.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/manual/middle/states/defaultBehavior.zh.md b/docs/manual/middle/states/defaultBehavior.zh.md index 315c326288e..196aaa70477 100644 --- a/docs/manual/middle/states/defaultBehavior.zh.md +++ b/docs/manual/middle/states/defaultBehavior.zh.md @@ -50,7 +50,11 @@ const graph = new G6.Graph({ - 含义:缩放画布; - `type: 'zoom-canvas'`; -- `sensitivity`:缩放灵敏度,支持 1-10 的数值,默认灵敏度为 5。 +- `sensitivity`:缩放灵敏度,支持 1-10 的数值,默认灵敏度为 5; +- `minZoom`:最小缩放比例; +- `maxZoom`:最大缩放比例; +- `enableOptimize`:是否开启性能优化,默认为 false,设置为 true 开启,开启后缩放比例小于 optimizeZoom 时自动隐藏非 keyShape; +- `optimizeZoom`:当 enableOptimize 为 true 时起作用,默认值为 0.7,表示当缩放到哪个比例时开始隐藏非 keyShape。 **提示:若要限定缩放尺寸,请在 graph 上设置  `minZoom`  和  `maxZoom`。** From 530854413bcfedf90d84e9099dea01dbc3413ba3 Mon Sep 17 00:00:00 2001 From: baizn <576375879@qq.com> Date: Fri, 20 Mar 2020 13:57:00 +0800 Subject: [PATCH 6/6] =?UTF-8?q?fix:=20=E5=A2=9E=E5=8A=A0=E7=BE=A4=E4=BA=8C?= =?UTF-8?q?=E7=BB=B4=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/manual/introduction.en.md | 6 ++++-- docs/manual/introduction.zh.md | 14 +++++++++++--- site/locale.json | 1 + site/pages/index.zh.tsx | 16 ++++++++++++++++ 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/docs/manual/introduction.en.md b/docs/manual/introduction.en.md index 0549659c7ea..af2ed639fef 100644 --- a/docs/manual/introduction.en.md +++ b/docs/manual/introduction.en.md @@ -114,9 +114,11 @@ Some implementations combined with front-end libraries from the third party: ## G6 Communication Group -Users are welcome to join the **G6 Communication Group** (It is a DingTalk group). We are also welcome the github issues. +Users are welcome to join the **G6 Communication Group** or **G6 Communication Group-2** (It is a DingTalk group). We are also welcome the github issues. - + + + ## How to Contribute diff --git a/docs/manual/introduction.zh.md b/docs/manual/introduction.zh.md index bfaec4fe3e0..dd6ad6225a5 100644 --- a/docs/manual/introduction.zh.md +++ b/docs/manual/introduction.zh.md @@ -54,6 +54,7 @@ G6 作为一款专业的图可视化引擎,具有以下特性: - [G6 核心概念](/zh/docs/manual/middle/graph) - [G6 高级指引](/zh/docs/manual/advanced/keyconcept/shape-and-properties) - [API](/zh/docs/api/Graph) +- [G6 Blog](https://www.yuque.com/antv/g6-blog) ## 快速上手 @@ -106,13 +107,20 @@ graph.render(); - 基于 G6 和 React 的可视化流程编辑器 - Workflow Designer; - 基于 G6 和 Vue 的可视化编辑器[](); -- 基于 G6 和 Vue 的可视化图形编辑器 - A visual graph editor based on G6 and Vue。 +- 基于 G6 和 Vue 的可视化图形编辑器 - A visual graph editor based on G6 and Vue; +- 基于 G6 和 React 实现的 ER 图编辑器; ## G6 图可视化交流群 -欢迎各界 G6 使用者、图可视化爱好者加入 **G6 图可视化交流群**(钉钉群,使用钉钉扫一扫加入)讨论与交流。 +欢迎各界 G6 使用者、图可视化爱好者加入 **G6 图可视化交流群** 及 **G6 图可视化交流二群**(钉钉群,使用钉钉扫一扫加入)讨论与交流。 - +> **G6 图可视化交流群** 已满员,该群会不定期移除不活跃的成员。 + +> 由于值班同学的时间和精力有限,**G6 图可视化交流二群** 中的问题我们会不定期回复。欢迎对 G6 感兴趣的同学加入到答疑中来,非常感谢! + + + + ## 如何贡献 diff --git a/site/locale.json b/site/locale.json index 1a7e5bdbc61..8a29bb8cc29 100644 --- a/site/locale.json +++ b/site/locale.json @@ -8,6 +8,7 @@ "更新": "Update", "感谢信赖": "WE ARE TRUSTED BY", "专注关系,完备基建": "Dedicated & Complete", + "G6·图可视化知多少": "G6 Graph Visualization Blog", "G6 是一个专注于关系数据的、完备的图可视化引擎": "G6 is a complete graph visualization engine, which focuses on relational data", "领域深钻,顶尖方案": "Top Solution", "扎根实际具体业务场景、结合业界领先成果,沉淀顶尖解决方案": "According to practical bussiness scenarios, we found out the top solutions", diff --git a/site/pages/index.zh.tsx b/site/pages/index.zh.tsx index 747651f562e..924af64a033 100644 --- a/site/pages/index.zh.tsx +++ b/site/pages/index.zh.tsx @@ -121,10 +121,26 @@ const IndexPage = () => { }, ]; + const insNotifications = [ + { + type: t('推荐'), + title: t('欢迎进入 2020 可视化智能研发时代'), + date: '2020.01.08', + link: 'https://www.yuque.com/antv/blog/ygdubv', + }, + { + type: t('推荐'), + title: t('G6·图可视化知多少'), + date: '2020.03.23', + link: 'https://www.yuque.com/antv/g6-blog', + }, + ]; + return ( <>