mirror of
https://gitee.com/antv/g6.git
synced 2024-12-05 05:09:07 +08:00
docs: 更新 combo combined 文档; docs: 新增自定义分类图 demo (#3600)
* chore: update version nums * docs: 更新 combo combined 文档; docs: 新增自定义分类图 demo * chore: refine
This commit is contained in:
parent
e0ab79dec2
commit
0179634024
10
package.json
10
package.json
@ -57,9 +57,13 @@
|
||||
"husky": "^4.2.5",
|
||||
"lerna": "^3.19.0",
|
||||
"lint-staged": "^10.2.2",
|
||||
"monaco-editor": "0.29.1",
|
||||
"monaco-editor-webpack-plugin": "5.0.0",
|
||||
"normalize-url": "^7.0.3",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^2.1.2",
|
||||
"pretty-quick": "^3.0.2",
|
||||
"react-monaco-editor": "0.40.0",
|
||||
"rimraf": "^3.0.0",
|
||||
"tslint": "^6.1.3",
|
||||
"tslint-config-airbnb": "^5.11.2",
|
||||
@ -80,6 +84,10 @@
|
||||
"react-scripts": "3.1.2"
|
||||
},
|
||||
"resolutions": {
|
||||
"@types/react": "^16.9.35"
|
||||
"@types/react": "^16.9.35",
|
||||
"monaco-editor": "0.29.1",
|
||||
"monaco-editor-webpack-plugin": "5.0.0",
|
||||
"react-monaco-editor": "^0.40.0",
|
||||
"normalize-url": "^4.1.0"
|
||||
}
|
||||
}
|
||||
|
@ -61,7 +61,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@antv/g-base": "^0.5.1",
|
||||
"@antv/g6-core": "*",
|
||||
"@antv/g6-core": "0.6.4",
|
||||
"@antv/util": "~2.0.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -66,7 +66,7 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@antv/g6-pc": "*"
|
||||
"@antv/g6-pc": "0.6.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.7.7",
|
||||
|
@ -75,9 +75,9 @@
|
||||
"@antv/g-canvas": "^0.5.2",
|
||||
"@antv/g-math": "^0.1.1",
|
||||
"@antv/g-svg": "^0.5.1",
|
||||
"@antv/g6-core": "*",
|
||||
"@antv/g6-element": "*",
|
||||
"@antv/g6-plugin": "*",
|
||||
"@antv/g6-core": "0.6.4",
|
||||
"@antv/g6-element": "0.6.4",
|
||||
"@antv/g6-plugin": "0.6.4",
|
||||
"@antv/hierarchy": "^0.6.7",
|
||||
"@antv/layout": "^0.2.1",
|
||||
"@antv/matrix-util": "^3.1.0-beta.3",
|
||||
|
@ -22,7 +22,7 @@
|
||||
"@antv/g-base": "^0.5.1",
|
||||
"@antv/g-canvas": "^0.5.2",
|
||||
"@antv/g-svg": "^0.5.2",
|
||||
"@antv/g6-core": "*",
|
||||
"@antv/g6-core": "0.6.4",
|
||||
"@antv/matrix-util": "^3.1.0-beta.3",
|
||||
"@antv/scale": "^0.3.4",
|
||||
"@antv/util": "^2.0.9",
|
||||
|
@ -71,7 +71,7 @@ outerLayout: new G6.Layout['gForce']({
|
||||
});
|
||||
```
|
||||
|
||||
**Type**: Object<br />**Default**: GForce Instance<br />**Required**: false<br />**Description**: The outer layout instance, should be a sync layout method. Refer to the corresponding layout docs. The default configuration of the `outerLayout` is:
|
||||
**Type**: Object<br />**Default**: GForce Instance<br />**Required**: false<br />**Description**: The outer layout instance. Refer to the corresponding layout docs. The default configuration of the `outerLayout` is:
|
||||
|
||||
```javascript
|
||||
outerLayout: new G6.Layout['gForce']({
|
||||
@ -92,7 +92,7 @@ innerLayout: new G6.Layout['grid']({
|
||||
});
|
||||
```
|
||||
|
||||
**Type**:Object<br />**Default**:Concentric Instance<br />**Required**:false<br />**Description**: The layout method for the items inside a combo. Refer to the corresponding layout docs. The default configuration of the `outerLayout` is:
|
||||
**Type**:Object<br />**Default**:Concentric Instance<br />**Required**:false<br />**Description**: The layout method for the items inside a combo, should be a sync layout method. Refer to the corresponding layout docs. The default configuration of the `outerLayout` is:
|
||||
|
||||
```javascript
|
||||
outerLayout: new G6.Layout['concentric']({
|
||||
|
@ -71,7 +71,7 @@ outerLayout: new G6.Layout['gForce']({
|
||||
});
|
||||
```
|
||||
|
||||
**类型**:Object<br />**默认值**:GForce 实例<br />**是否必须**:false<br />**说明**:最外层的布局算法,需要使用同步的布局算法,默认为 gForce。具体参数详见被使用布局的文档。
|
||||
**类型**:Object<br />**默认值**:GForce 实例<br />**是否必须**:false<br />**说明**:最外层的布局算法,默认为 gForce。具体参数详见被使用布局的文档。
|
||||
默认情况下 gForce 布局将使用以下参数:
|
||||
|
||||
```javascript
|
||||
@ -93,7 +93,7 @@ innerLayout: new G6.Layout['grid']({
|
||||
});
|
||||
```
|
||||
|
||||
**类型**:Object<br />**默认值**:Concentric 实例<br />**是否必须**:false<br />**说明**:ombo 内部的布局算法,默认为 concentric。具体参数详见被使用布局的文档。
|
||||
**类型**:Object<br />**默认值**:Concentric 实例<br />**是否必须**:false<br />**说明**:combo 内部的布局算法,需要使用同步的布局算法,默认为 concentric。具体参数详见被使用布局的文档。
|
||||
默认情况下 concentric 布局将使用以下参数:
|
||||
|
||||
```javascript
|
||||
|
@ -20,7 +20,8 @@ Notice that the layouts for Graph cannot be used on TreeGraph.
|
||||
- [Dagre Layout](./dagre): Arranges the nodes hierarchically;
|
||||
- [Concentric Layout](./concentric): Arranges the nodes on concentric circles;
|
||||
- [Grid Layout](./grid): Arranges the nodes on grid.
|
||||
- [Combo Force Layout](./comboForce):_New feature of V3.5_ Designed for graph with combos.- [Combo Combined Layout](./comboCombined):_New feature of V4.6_ Designed for graph with combos. Support configuring the layout for items inside a combo and the layout for the outer combos and nodes.
|
||||
- [Combo Force Layout](./comboForce):_New feature of V3.5_ Designed for graph with combos.
|
||||
- [Combo Combined Layout](./comboCombined):_New feature of V4.6_ Designed for graph with combos. Support configuring the layout for items inside a combo and the layout for the outer combos and nodes.
|
||||
|
||||
## Configure to Gaph
|
||||
|
||||
|
@ -286,3 +286,17 @@ General graph layout API: [General Graph Layout API](/en/docs/api/graphLayout/gu
|
||||
| depthRepulsiveForceScale | Number | | 2 | The scale for adjusting the strength of repulsive force between nodes with different depths. The range is [1, Infinity]. Lager the depth difference, larger the attractive force strength |
|
||||
| velocityDecay | Number | 0.2 | 0.6 | The decay speed of the moving velocity of nodes for each iteration |
|
||||
| workerEnabled | Boolean | true / false | false | Whether to enable the web-worker in case layout calculation takes too long to block page interaction |
|
||||
|
||||
### Combo Combined
|
||||
|
||||
<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*ZlvWS7xOkjMAAAAAAAAAAAAAARQnAQ' width=300 alt='img' /><br />**API**:[Combo Combined API](/en/docs/api/graphLayout/comboCombined)<br />**Parameters**:
|
||||
|
||||
| Name | Type | Example/Options | Default | Description |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| center | Array | [ 0, 0 ] | The center of the graph | The center of the layout |
|
||||
| nodeSize | Array / Number | 10 | 10 | The diameter of the node. It is used for preventing node overlappings. If `nodeSize` is not assigned, the size property in node data will take effect. If the size in node data does not exist either, `nodeSize` is assigned to 10 by default |
|
||||
| spacing | Number / Function | 10 | 0 | Takes effect when the `preventNodeOverlap` or `preventOverlap` is `true`. The minimum distances between nodes and combos to prevent overlappings. It can be a function to assign different values for different items |
|
||||
| comboPadding | Number / Function | 10 | 10 | The padding inside a Combo, not for rendering but for force calculation. We suggest to assign the corresponding values to the graph config |
|
||||
| outerLayout | Object | GForce instance | ForceAtlas2 instance | The layout instance for the outer combos. gForce by default. For the parameters, please refer to the corresponding layout docs |
|
||||
| innerLayout | Object | Concentric instance | Grid instance | The inner layout inside combos. Concentric by default. It should be synchronous algorithm. For the parameters, please refer to the corresponding layout docs |
|
||||
| workerEnabled | Boolean | true / false | false | Whether to enable the web-worker in case layout calculation takes too long to block page interaction |
|
||||
|
@ -26,6 +26,7 @@ order: 0
|
||||
- [Concentric Layout](#concentric):同心圆布局;
|
||||
- [Grid Layout](#grid):网格布局;
|
||||
- [Combo Force Layout](#combo-force):*V3.5 新增。*适用于带有 combo 图的力导向布局,推荐有 combo 的图使用该布局。
|
||||
- [Combo Combined Layout](#combo-combined):*V4.6 新增。*适用于带有 combo 的图,可自由组合内外布局,默认情况下可以有较好的效果,推荐有 combo 的图使用该布局。
|
||||
|
||||
## 配置一般图布局
|
||||
|
||||
@ -286,3 +287,17 @@ const graph = new G6.Graph({
|
||||
| depthRepulsiveForceScale | Number | | 2 | 根据边两端节点层级差距的调整斥力系数的因子,取值范围 [1, Infinity]。层级差距越大,斥力越大 |
|
||||
| velocityDecay | Number | 0.4 | 0.6 | 每个迭代节点运动速度衰减参数 |
|
||||
| workerEnabled | Boolean | true / false | false | 是否启用 web-worker 以防布局计算时间过长阻塞页面交互 |
|
||||
|
||||
### Combo Combined
|
||||
|
||||
<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*ZlvWS7xOkjMAAAAAAAAAAAAAARQnAQ' width=300 alt='img' /><br />**API**:[Combo Combined API](/zh/docs/api/graphLayout/comboCombined)<br />**参数**:
|
||||
|
||||
| 参数名 | 类型 | 示例 | 默认值 | 说明 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| center | Array | [ 0, 0 ] | 图的中心 | 布局的中心 |
|
||||
| nodeSize | Array / Number | 10 | 10 | 节点大小(直径)。用于碰撞检测。若不指定,则根据传入的节点的 size 属性计算。若即不指定,节点中也没有 `size`,则默认大小为 `10` |
|
||||
| spacing | Number / Function | 10 | 0 | `preventNodeOverlap` 或 `preventOverlap` 为 `true` 时生效, 防止重叠时节点/ combo 边缘间距的最小值。可以是回调函数, 为不同节点设置不同的最小间距 |
|
||||
| comboPadding | Number / Function | 10 | 10 | Combo 内部的 padding 值,不用于渲染,仅用于计算力。推荐设置为与视图上 combo 内部 padding 值相同的值 |
|
||||
| outerLayout | Object | GForce 实例 | ForceAtlas2 实例 | 最外层的布局算法,需要使用同步的布局算法,默认为 gForce。具体参数详见被使用布局的文档 |
|
||||
| innerLayout | Object | Concentric 实例 | Grid 实例 | combo 内部的布局算法,默认为 concentric。具体参数详见被使用布局的文档 |
|
||||
| workerEnabled | Boolean | true / false | false | 是否启用 web-worker 以防布局计算时间过长阻塞页面交互 |
|
296
packages/site/examples/case/graphDemos/demo/customFlow.js
Normal file
296
packages/site/examples/case/graphDemos/demo/customFlow.js
Normal file
@ -0,0 +1,296 @@
|
||||
import G6 from '@antv/g6';
|
||||
/**
|
||||
* by Zhihui Hu
|
||||
* https://www.zhihu.com/people/wisdommm
|
||||
*/
|
||||
|
||||
const width = document.getElementById('container').scrollWidth;
|
||||
const height = document.getElementById('container').scrollHeight || 500;
|
||||
|
||||
/** ====== data preparation ======= */
|
||||
// the first layer nodes
|
||||
const baseData = {
|
||||
nodes: [
|
||||
{ id: "intention1", time: "2022/03/20", title: "User Intend", expandRange: [0, 2], show: false, startPosition: 0, endPosition: 0 },
|
||||
{ id: "intention2", time: "2022/03/20", title: "User Intend", expandRange: [1, 3], show: false, startPosition: 0, endPosition: 0 },
|
||||
{ id: "intention3", time: "2022/03/20", title: "User Intend", expandRange: [3, 5], show: false, startPosition: 0, endPosition: 0 },
|
||||
],
|
||||
edges: [
|
||||
{ id: "edge1", source: "intention1", target: "intention2" },
|
||||
{ id: "edge2", source: "intention2", target: "intention3" },
|
||||
]
|
||||
};
|
||||
baseData.nodes.forEach(node => {
|
||||
node.type = 'customNode';
|
||||
});
|
||||
// layout for the first layer nodes
|
||||
const gridLayout = new G6.Layout['grid']({
|
||||
rows: 1,
|
||||
width,
|
||||
sortBy: 'id'
|
||||
});
|
||||
gridLayout.init(baseData);
|
||||
gridLayout.execute()
|
||||
|
||||
// the second layer nodes
|
||||
const rangeData = {
|
||||
nodes: [
|
||||
{ id: "0", label: "Like" },
|
||||
{ id: "1", label: "Follow" },
|
||||
{ id: "2", label: "Collect" },
|
||||
{ id: "3", label: "Shop" },
|
||||
{ id: "4", label: "Pay" },
|
||||
{ id: "5", label: "Comment" }
|
||||
],
|
||||
};
|
||||
rangeData.nodes.forEach(node => node.visible = false);
|
||||
|
||||
|
||||
const graphData = {
|
||||
nodes: baseData.nodes.concat(rangeData.nodes),
|
||||
edges: baseData.edges
|
||||
}
|
||||
|
||||
/** ====== custom a node type ======= */
|
||||
G6.registerNode('customNode',
|
||||
{
|
||||
draw(cfg, group) {
|
||||
group.shapeMap = {};
|
||||
const rect = group.addShape('circle', {
|
||||
attrs: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
r: 50,
|
||||
lineWidth: 1,
|
||||
fillOpacity: 1,
|
||||
radius: 12,
|
||||
stroke: 'rgba(0,0,0,0.2)',
|
||||
lineWidth: 1,
|
||||
fill: '#fff',
|
||||
},
|
||||
name: 'rect-intention',
|
||||
});
|
||||
// title
|
||||
group.addShape('text', {
|
||||
attrs: {
|
||||
x: 0,
|
||||
y: -10,
|
||||
text: cfg.title,
|
||||
fontSize: 14,
|
||||
fill: '#000',
|
||||
fontWeight: 'bold',
|
||||
textAlign: 'center'
|
||||
},
|
||||
name: 'rect-title',
|
||||
});
|
||||
// time
|
||||
group.addShape('text', {
|
||||
attrs: {
|
||||
x: 0,
|
||||
y: 20,
|
||||
text: cfg.time,
|
||||
fontSize: 14,
|
||||
fill: '#999',
|
||||
textAlign: 'center'
|
||||
},
|
||||
name: 'rect-time',
|
||||
});
|
||||
if (cfg.expandRange) {
|
||||
// expand button
|
||||
group.addShape('rect', {
|
||||
attrs: {
|
||||
x: -32.5,
|
||||
y: 35,
|
||||
width: 65,
|
||||
height: 20,
|
||||
radius: 8,
|
||||
stroke: '#FF6107',
|
||||
lineWidth: 1,
|
||||
fill: '#FFF',
|
||||
},
|
||||
name: 'rectBtn',
|
||||
});
|
||||
// button text
|
||||
group.addShape('text', {
|
||||
attrs: {
|
||||
x: 0,
|
||||
y: 51,
|
||||
text: cfg.show ? '- collapse' : '+ expand',
|
||||
fill: '#FF6107',
|
||||
fontSize: 12,
|
||||
textAlign: 'center'
|
||||
},
|
||||
capture: false,
|
||||
name: 'rectBtn-text',
|
||||
});
|
||||
group.shapeMap['rectBtn-text'] = expandShape;
|
||||
}
|
||||
|
||||
const expandShape = group.addShape('polygon', {
|
||||
attrs: {
|
||||
points: [
|
||||
[30, 60],
|
||||
[-30, 60],
|
||||
[cfg.startPosition, 200],
|
||||
[cfg.endPosition, 200],
|
||||
],
|
||||
fill: 'l(90) 0:rgba(255,97,7,0.18) 1:rgba(255,97,7,0)',
|
||||
opacity: 0.5
|
||||
},
|
||||
visible: false,
|
||||
name: 'polygon-shape',
|
||||
});
|
||||
expandShape.toBack();
|
||||
group.shapeMap['polygon-shape'] = expandShape;
|
||||
|
||||
return rect;
|
||||
},
|
||||
update: (cfg, item) => {
|
||||
const group = item.getContainer();
|
||||
const expandText = group.shapeMap?.['rectBtn-text'] || group.find(e => e.get('name') === 'rectBtn-text');
|
||||
expandText.attr({
|
||||
text: cfg.show ? '- collapse' : '+ expand'
|
||||
});
|
||||
const expandShape = group.shapeMap?.['polygon-shape'] || group.find(e => e.get('name') === 'polygon-shape');
|
||||
if (cfg.show) {
|
||||
expandShape.set('visible', true);
|
||||
expandShape.attr({
|
||||
points: [
|
||||
[30, 60],
|
||||
[-30, 60],
|
||||
[cfg.startPosition, 200],
|
||||
[cfg.endPosition, 200],
|
||||
],
|
||||
opacity: 0,
|
||||
});
|
||||
expandShape.animate({ opacity: 1 }, { duration: 300, repeat: false });
|
||||
} else {
|
||||
expandShape.set('visible', false);
|
||||
expandShape.animate({ opacity: 0 }, { duration: 300, repeat: false });
|
||||
}
|
||||
}
|
||||
},
|
||||
'single-node'
|
||||
);
|
||||
|
||||
|
||||
/** ====== init the graph ======= */
|
||||
const graph = new G6.Graph({
|
||||
container: 'container',
|
||||
width,
|
||||
height,
|
||||
modes: {
|
||||
default: ['drag-canvas']
|
||||
},
|
||||
defaultNode: {
|
||||
type: 'circle',
|
||||
style: {
|
||||
r: 30,
|
||||
fill: '#fff',
|
||||
stroke: '#ccc',
|
||||
lineWidth: 1,
|
||||
},
|
||||
},
|
||||
defaultEdge: {
|
||||
style: {
|
||||
color: "#fff",
|
||||
stroke: "#FF6107",
|
||||
lineWidth: 12,
|
||||
opacity: 0.6
|
||||
}
|
||||
}
|
||||
});
|
||||
graph.read(graphData);
|
||||
|
||||
|
||||
/** ====== bind listener ======= */
|
||||
graph.on('rectBtn:click', (e) => {
|
||||
const model = e.item.getModel();
|
||||
const { expandRange } = model;
|
||||
if (expandRange) {
|
||||
showRoute(model);
|
||||
}
|
||||
});
|
||||
const showRoute = (nodeData) => {
|
||||
nodeData.show = !nodeData.show;
|
||||
|
||||
let { nodes, edges } = graphData;
|
||||
const routeNodes = [];
|
||||
const routeEdges = [];
|
||||
const routeNodesMap = {};
|
||||
|
||||
// the nodes will be shown in the second layer
|
||||
let showRangeIds = new Set();
|
||||
baseData.nodes.forEach(node => {
|
||||
if (!node.show) return;
|
||||
const { expandRange } = node;
|
||||
for (let i = +expandRange[0]; i < +expandRange[1] + 1; i++) {
|
||||
showRangeIds.add(i);
|
||||
}
|
||||
});
|
||||
showRangeIds = Array.from(showRangeIds);
|
||||
showRangeIds.sort((a, b) => a - b);
|
||||
|
||||
const rangeLayoutNodes = [];
|
||||
rangeData.nodes.forEach(node => {
|
||||
const showIdx = showRangeIds.indexOf(+node.id);
|
||||
if (showIdx > -1) {
|
||||
graph.showItem(node.id);
|
||||
rangeLayoutNodes.push(node);
|
||||
}
|
||||
else graph.hideItem(node.id);
|
||||
});
|
||||
|
||||
// layout for the second row nodes
|
||||
const rangeGridLayout = new G6.Layout['grid']({
|
||||
rows: 1,
|
||||
width: 1000,
|
||||
begin: [0, 200]
|
||||
});
|
||||
rangeGridLayout.init({ nodes: rangeLayoutNodes, edges: [] });
|
||||
rangeGridLayout.execute();
|
||||
rangeLayoutNodes.forEach(node => graph.update(node.id, { x: node.x, y: node.y }))
|
||||
|
||||
// update the 'show', 'startPosition', and 'endPosition' for first layer node
|
||||
baseData.nodes.forEach((node) => {
|
||||
const { id: nodeId, expandRange, x } = node;
|
||||
if (!node.show) {
|
||||
graph.updateItem(nodeId, { show: false });
|
||||
return;
|
||||
}
|
||||
const [start, end] = expandRange;
|
||||
graph.updateItem(nodeId, {
|
||||
show: true,
|
||||
// the position for the bottom vertexes of the range polygon
|
||||
startPosition: graph.findById(`${start}`).getModel().x - 30 - x,
|
||||
endPosition: graph.findById(`${end}`).getModel().x + 30 - x,
|
||||
});
|
||||
});
|
||||
|
||||
// remove the blue range edges
|
||||
graph.getEdges().forEach(edge => {
|
||||
if (edge.getModel().tag === 'range') graph.removeItem(edge);
|
||||
});
|
||||
|
||||
// add new blue range edges
|
||||
showRangeIds.forEach((id, i) => {
|
||||
if (i === 0) return;
|
||||
graph.addItem('edge', {
|
||||
id: `edge-${Math.random()}`,
|
||||
source: `${showRangeIds[i - 1]}`,
|
||||
target: `${id}`,
|
||||
tag: 'range',
|
||||
style: {
|
||||
lineWidth: 2,
|
||||
stroke: '#8CC2FC'
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
if (typeof window !== 'undefined')
|
||||
window.onresize = () => {
|
||||
if (!graph || graph.get('destroyed')) return;
|
||||
if (!container || !container.scrollWidth || !container.scrollHeight) return;
|
||||
graph.changeSize(container.scrollWidth, container.scrollHeight);
|
||||
};
|
@ -51,6 +51,14 @@
|
||||
"en": "Donut Transfer"
|
||||
},
|
||||
"screenshot": "https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*YK6yRIfKQaIAAAAAAAAAAAAAARQnAQ"
|
||||
},
|
||||
{
|
||||
"filename": "customFlow.js",
|
||||
"title": {
|
||||
"zh": "自定义分类图",
|
||||
"en": "Custom Category Graph"
|
||||
},
|
||||
"screenshot": "https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*hk1QTqVIHnIAAAAAAAAAAAAAARQnAQ"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "@antv/g6-site",
|
||||
"version": "4.5.5",
|
||||
"version": "4.6.4",
|
||||
"description": "G6 sites deployed on gh-pages",
|
||||
"keywords": [
|
||||
"antv",
|
||||
@ -44,7 +44,10 @@
|
||||
"@types/react-dom": "^16.9.8",
|
||||
"gatsby": "^2.24.40",
|
||||
"gh-pages": "^2.1.1",
|
||||
"monaco-editor": "0.29.1",
|
||||
"monaco-editor-webpack-plugin": "5.0.0",
|
||||
"react-i18next": "^11.1.0",
|
||||
"react-monaco-editor": "0.40.0",
|
||||
"typedoc": "^0.17.6",
|
||||
"typedoc-plugin-markdown": "^2.2.11",
|
||||
"typescript": "^3.6.5"
|
||||
|
Loading…
Reference in New Issue
Block a user