-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: 开发 react-node-registry 包用于用户自定义 react 节点
- 通过监听 properties 变化的事件,触发节点的更新 - 通过 Portal 的方式,可以获取到宿主系统的数据(比如状态),保持组件渲染和系统同步
- Loading branch information
1 parent
74a0882
commit 9afcda9
Showing
20 changed files
with
788 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
import React, { FC, useContext } from 'react' | ||
import LogicFlow from '@logicflow/core' | ||
import { | ||
register, | ||
ReactNodeProps, | ||
Portal, | ||
} from '@logicflow/react-node-registry' | ||
import { Button, Card } from 'antd' | ||
|
||
import styles from './index.less' | ||
|
||
const LFReactPortalProvider = Portal.getProvider() // 注意,一个 LogicFlow 实例只能生命一个 portal provider | ||
const ThemeContext = React.createContext('light') | ||
|
||
const NodeComponent: FC<ReactNodeProps> = ({ node }) => { | ||
const theme = useContext(ThemeContext) | ||
const data = node.getData() | ||
if (!data.properties) data.properties = {} | ||
|
||
return ( | ||
<div className={`react-algo-node ${theme === 'light' ? 'light' : 'dark'}`}> | ||
<img src={require('@/assets/didi.png')} alt="滴滴出行" /> | ||
<span>{data.properties.name as string}</span> | ||
</div> | ||
) | ||
} | ||
|
||
export default class Example extends React.Component { | ||
private container!: HTMLDivElement | ||
private count = 0 | ||
private timer?: ReturnType<typeof setTimeout> | ||
|
||
state = { | ||
theme: 'light', | ||
} | ||
|
||
componentDidMount() { | ||
const lf = new LogicFlow({ | ||
container: this.container, | ||
// width: 800, | ||
// height: 600, | ||
}) | ||
|
||
lf.render({ | ||
nodes: [ | ||
{ | ||
type: 'rect', | ||
x: 400, | ||
y: 100, | ||
text: '???', | ||
properties: { | ||
name: '矩形', | ||
}, | ||
}, | ||
], | ||
}) | ||
|
||
register( | ||
{ | ||
type: 'custom-react-node', | ||
component: NodeComponent, | ||
}, | ||
lf, | ||
) | ||
|
||
const node = lf.addNode({ | ||
id: 'react-node-1', | ||
type: 'custom-react-node', | ||
x: 80, | ||
y: 80, | ||
properties: { | ||
name: '今日出行', | ||
width: 120, | ||
height: 28, | ||
}, | ||
}) | ||
console.log('node --->>>', node) | ||
|
||
const update = () => { | ||
// lf.setProperties('react-node-1', { name: `逻辑回归 ${(this.count += 1)}` }) | ||
node.setProperty('name', `今日出行 ${(this.count += 1)}`) | ||
this.timer = setTimeout(update, 1000) | ||
} | ||
|
||
update() | ||
} | ||
|
||
componentWillUnmount() { | ||
console.log('0-0-0 componentWillUnmount 0-0-0') | ||
if (this.timer) { | ||
clearTimeout(this.timer) | ||
} | ||
} | ||
|
||
changeTheme = () => { | ||
this.setState({ | ||
theme: this.state.theme === 'light' ? 'dark' : 'light', | ||
}) | ||
} | ||
|
||
refContainer = (container: HTMLDivElement) => { | ||
this.container = container | ||
} | ||
|
||
render() { | ||
return ( | ||
<Card title="React 自定义节点"> | ||
<ThemeContext.Provider value={this.state.theme}> | ||
<LFReactPortalProvider /> | ||
</ThemeContext.Provider> | ||
|
||
<Button onClick={this.changeTheme}> | ||
{this.state.theme === 'light' ? '切换到暗色' : '切换到亮色'} | ||
</Button> | ||
<div | ||
ref={this.refContainer} | ||
id="graph" | ||
className={styles.viewport} | ||
></div> | ||
</Card> | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
.viewport { | ||
position: relative; | ||
height: 80vh; | ||
overflow: hidden; | ||
} | ||
|
||
:global { | ||
.react-algo-node { | ||
display: flex; | ||
align-items: center; | ||
width: 100%; | ||
height: 100%; | ||
border: 1px solid #e59b68; | ||
border-radius: 14px; | ||
|
||
img { | ||
width: 24px; | ||
height: 24px; | ||
} | ||
|
||
span { | ||
margin-left: 4px; | ||
color: #000000a6; | ||
font-size: 12px; | ||
} | ||
|
||
&.dark { | ||
background-color: #141414; | ||
|
||
span { | ||
color: #fff; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import React, { FC } from 'react' | ||
import LogicFlow from '@logicflow/core' | ||
import { register, ReactNodeProps } from '@logicflow/react-node-registry' | ||
import { Card } from 'antd' | ||
|
||
import styles from './index.less' | ||
|
||
const NodeComponent: FC<ReactNodeProps> = ({ node }) => { | ||
const data = node.getData() | ||
if (!data.properties) data.properties = {} | ||
|
||
return ( | ||
<div className="react-algo-node"> | ||
<img src={require('@/assets/didi.png')} alt="滴滴出行" /> | ||
<span>{data.properties.name as string}</span> | ||
</div> | ||
) | ||
} | ||
|
||
export default class Example extends React.Component { | ||
private container!: HTMLDivElement | ||
private count = 0 | ||
private timer?: ReturnType<typeof setTimeout> | ||
|
||
componentDidMount() { | ||
const lf = new LogicFlow({ | ||
container: this.container, | ||
// width: 800, | ||
// height: 600, | ||
}) | ||
|
||
lf.render({ | ||
nodes: [ | ||
{ | ||
type: 'rect', | ||
x: 400, | ||
y: 100, | ||
text: '???', | ||
properties: { | ||
name: '矩形', | ||
}, | ||
}, | ||
], | ||
}) | ||
|
||
register( | ||
{ | ||
type: 'custom-react-node', | ||
component: NodeComponent, | ||
}, | ||
lf, | ||
) | ||
|
||
const node = lf.addNode({ | ||
id: 'react-node-1', | ||
type: 'custom-react-node', | ||
x: 80, | ||
y: 80, | ||
properties: { | ||
name: '今日出行', | ||
width: 120, | ||
height: 28, | ||
}, | ||
}) | ||
console.log('node --->>>', node) | ||
|
||
const update = () => { | ||
// lf.setProperties('react-node-1', { name: `逻辑回归 ${(this.count += 1)}` }) | ||
node.setProperty('name', `今日出行 ${(this.count += 1)}`) | ||
this.timer = setTimeout(update, 1000) | ||
} | ||
|
||
update() | ||
} | ||
|
||
componentWillUnmount() { | ||
console.log('0-0-0 componentWillUnmount 0-0-0') | ||
if (this.timer) { | ||
clearTimeout(this.timer) | ||
} | ||
} | ||
|
||
refContainer = (container: HTMLDivElement) => { | ||
this.container = container | ||
} | ||
|
||
render() { | ||
return ( | ||
<Card title="React 自定义节点"> | ||
<div | ||
ref={this.refContainer} | ||
id="graph" | ||
className={styles.viewport} | ||
></div> | ||
</Card> | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.