Skip to content

Commit

Permalink
g6 in react demo
Browse files Browse the repository at this point in the history
  • Loading branch information
zhanning.bzn committed Oct 5, 2019
0 parents commit a7adcbd
Show file tree
Hide file tree
Showing 16 changed files with 913 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
node_modules/
26 changes: 26 additions & 0 deletions README.md
@@ -0,0 +1,26 @@
### 如何在React中使用G6?
在平时的答疑工作中,经常会遇到「如何在React中使用G6」的问题,为了让G6用户能够在开发中很方便地接入G6,我们提供一个G6在React中使用的Demo,供开发者参考。

`说明:鉴于目前React hooks比较🔥, 且大多数React开发者已经在使用hooks进行业务开发,因此,我们提供的Demo也是基于hooks的。`

### 功能
我们提供的Demo,包括了以下功能:
- 自定义节点;
- 自定义边;
- 节点的tooltip;
- 边的tooltip;
- 节点的ContextMenu;
- tooltip及ContextMenu如何渲染自定义的React组件。

### Development
```
# clone repo
$ git clone https://github.com/baizn/g6-in-react.git
# install dependencies
$ npm install
# start server
$ npm start
```
29 changes: 29 additions & 0 deletions package.json
@@ -0,0 +1,29 @@
{
"name": "g6-in-react",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "umi dev",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/baizn/g6-in-react.git"
},
"keywords": [
"g6"
],
"author": "baizn",
"license": "ISC",
"bugs": {
"url": "https://github.com/baizn/g6-in-react/issues"
},
"homepage": "https://github.com/baizn/g6-in-react#readme",
"dependencies": {
"@antv/g6": "^3.0.7-beta.1",
"antd": "^3.23.5",
"dagre": "^0.8.4",
"graphlib": "^2.1.7"
}
}
6 changes: 6 additions & 0 deletions pages/.umi/history.js
@@ -0,0 +1,6 @@
// create history
const history = require('umi/lib/createHistory').default({
basename: window.routerBase,
});
window.g_history = history;
export default history;
3 changes: 3 additions & 0 deletions pages/.umi/polyfills.js
@@ -0,0 +1,3 @@
import 'core-js';
import 'regenerator-runtime/runtime';

88 changes: 88 additions & 0 deletions pages/.umi/router.js
@@ -0,0 +1,88 @@
import React from 'react';
import { Router as DefaultRouter, Route, Switch } from 'react-router-dom';
import dynamic from 'umi/dynamic';
import renderRoutes from 'umi/lib/renderRoutes';
import history from '@tmp/history';

const Router = DefaultRouter;

const routes = [
{
path: '/component/contextMenu',
exact: true,
component: require('../component/contextMenu.js').default,
},
{
path: '/component/edgTooltip',
exact: true,
component: require('../component/edgTooltip.js').default,
},
{
path: '/component',
exact: true,
component: require('../component/index.js').default,
},
{
path: '/component/nodeTooltip',
exact: true,
component: require('../component/nodeTooltip.js').default,
},
{
path: '/data',
exact: true,
component: require('../data.js').default,
},
{
path: '/',
exact: true,
component: require('../index.js').default,
},
{
path: '/registerShape',
exact: true,
component: require('../registerShape.js').default,
},
{
component: () =>
React.createElement(
require('/Users/moyee/.config/yarn/global/node_modules/umi-build-dev/lib/plugins/404/NotFound.js')
.default,
{ pagesPath: 'pages', hasRoutesInConfig: false },
),
},
];
window.g_routes = routes;
const plugins = require('umi/_runtimePlugin');
plugins.applyForEach('patchRoutes', { initialValue: routes });

export { routes };

export default class RouterWrapper extends React.Component {
unListen = () => {};

constructor(props) {
super(props);

// route change handler
function routeChangeHandler(location, action) {
plugins.applyForEach('onRouteChange', {
initialValue: {
routes,
location,
action,
},
});
}
this.unListen = history.listen(routeChangeHandler);
routeChangeHandler(history.location);
}

componentWillUnmount() {
this.unListen();
}

render() {
const props = this.props || {};
return <Router history={history}>{renderRoutes(routes, props)}</Router>;
}
}
151 changes: 151 additions & 0 deletions pages/.umi/umi.js
@@ -0,0 +1,151 @@
import './polyfills';
import history from './history';

import React from 'react';
import ReactDOM from 'react-dom';
import findRoute, {
getUrlQuery,
} from '/Users/moyee/.config/yarn/global/node_modules/umi-build-dev/lib/findRoute.js';

// runtime plugins
const plugins = require('umi/_runtimePlugin');
window.g_plugins = plugins;
plugins.init({
validKeys: [
'patchRoutes',
'render',
'rootContainer',
'modifyRouteProps',
'onRouteChange',
'modifyInitialProps',
'initialProps',
],
});

// render
let clientRender = async () => {
window.g_isBrowser = true;
let props = {};
// Both support SSR and CSR
if (window.g_useSSR) {
// 如果开启服务端渲染则客户端组件初始化 props 使用服务端注入的数据
props = window.g_initialData;
} else {
const pathname = location.pathname;
const activeRoute = findRoute(require('@tmp/router').routes, pathname);
// 在客户端渲染前,执行 getInitialProps 方法
// 拿到初始数据
if (
activeRoute &&
activeRoute.component &&
activeRoute.component.getInitialProps
) {
const initialProps = plugins.apply('modifyInitialProps', {
initialValue: {},
});
props = activeRoute.component.getInitialProps
? await activeRoute.component.getInitialProps({
route: activeRoute,
isServer: false,
location,
...initialProps,
})
: {};
}
}
const rootContainer = plugins.apply('rootContainer', {
initialValue: React.createElement(require('./router').default, props),
});
ReactDOM[window.g_useSSR ? 'hydrate' : 'render'](
rootContainer,
document.getElementById('root'),
);
};
const render = plugins.compose(
'render',
{ initialValue: clientRender },
);

const moduleBeforeRendererPromises = [];
// client render
if (__IS_BROWSER) {
Promise.all(moduleBeforeRendererPromises)
.then(() => {
render();
})
.catch(err => {
window.console && window.console.error(err);
});
}

// export server render
let serverRender, ReactDOMServer;
if (!__IS_BROWSER) {
serverRender = async (ctx = {}) => {
// ctx.req.url may be `/bar?locale=en-US`
const [pathname] = (ctx.req.url || '').split('?');
const history = require('@tmp/history').default;
history.push(ctx.req.url);
let props = {};
const activeRoute =
findRoute(require('./router').routes, pathname) || false;
if (
activeRoute &&
activeRoute.component &&
activeRoute.component.getInitialProps
) {
const initialProps = plugins.apply('modifyInitialProps', {
initialValue: {},
});
// patch query object
const location = history.location
? { ...history.location, query: getUrlQuery(history.location.search) }
: {};
props = await activeRoute.component.getInitialProps({
route: activeRoute,
isServer: true,
location,
// only exist in server
req: ctx.req || {},
res: ctx.res || {},
...initialProps,
});
props = plugins.apply('initialProps', {
initialValue: props,
});
} else {
// message activeRoute or getInitialProps not found
console.log(
!activeRoute
? `${pathname} activeRoute not found`
: `${pathname} activeRoute's getInitialProps function not found`,
);
}
const rootContainer = plugins.apply('rootContainer', {
initialValue: React.createElement(require('./router').default, props),
});
const htmlTemplateMap = {};
return {
htmlElement:
activeRoute && activeRoute.path
? htmlTemplateMap[activeRoute.path]
: '',
rootContainer,
matchPath: activeRoute && activeRoute.path,
g_initialData: props,
};
};
// using project react-dom version
// https://github.com/facebook/react/issues/13991
ReactDOMServer = require('react-dom/server');
}

export { ReactDOMServer };
export default (__IS_BROWSER ? null : serverRender);

// hot module replacement
if (__IS_BROWSER && module.hot) {
module.hot.accept('./router', () => {
clientRender();
});
}
Empty file added pages/.umi/umiExports.js
Empty file.
59 changes: 59 additions & 0 deletions pages/component/contextMenu.js
@@ -0,0 +1,59 @@
import React from 'react'
import { Menu, Icon } from 'antd'
import 'antd/es/menu/style/css'
const { SubMenu } = Menu

const NodeContextMenu = ({ x = -300, y = 0 }) => {
return <Menu style={{ width: 256, position: 'absolute', left: x, top: y }} mode="vertical">
<SubMenu
key="sub1"
title={
<span>
<Icon type="mail" />
<span>Navigation One</span>
</span>
}
>
<Menu.ItemGroup title="Item 1">
<Menu.Item key="1">Option 1</Menu.Item>
<Menu.Item key="2">Option 2</Menu.Item>
</Menu.ItemGroup>
<Menu.ItemGroup title="Iteom 2">
<Menu.Item key="3">Option 3</Menu.Item>
<Menu.Item key="4">Option 4</Menu.Item>
</Menu.ItemGroup>
</SubMenu>
<SubMenu
key="sub2"
title={
<span>
<Icon type="appstore" />
<span>Navigation Two</span>
</span>
}
>
<Menu.Item key="5">Option 5</Menu.Item>
<Menu.Item key="6">Option 6</Menu.Item>
<SubMenu key="sub3" title="Submenu">
<Menu.Item key="7">Option 7</Menu.Item>
<Menu.Item key="8">Option 8</Menu.Item>
</SubMenu>
</SubMenu>
<SubMenu
key="sub4"
title={
<span>
<Icon type="setting" />
<span>Navigation Three</span>
</span>
}
>
<Menu.Item key="9">Option 9</Menu.Item>
<Menu.Item key="10">Option 10</Menu.Item>
<Menu.Item key="11">Option 11</Menu.Item>
<Menu.Item key="12">Option 12</Menu.Item>
</SubMenu>
</Menu>
}

export default NodeContextMenu

0 comments on commit a7adcbd

Please sign in to comment.