chore: add radial layout demo (#5532)

* chore: add radial layout demo

* fix: conversation

* feat: update snapshots

* fix: ci
This commit is contained in:
Joel Alan 2024-03-14 19:42:30 +08:00 committed by GitHub
parent 095f7fc8b3
commit f9b845a9da
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
32 changed files with 23427 additions and 2361 deletions

View File

@ -24,6 +24,12 @@ module.exports = {
'jsdoc/require-jsdoc': 0,
},
},
{
files: ['**/demo-to-test/**'],
rules: {
'@typescript-eslint/no-var-requires': 'off',
},
},
],
parser: '@typescript-eslint/parser',
parserOptions: {

View File

@ -22,6 +22,8 @@
]
},
"devDependencies": {
"@babel/core": "^7.24.0",
"@babel/plugin-transform-typescript": "^7.23.6",
"@commitlint/cli": "^18.6.1",
"@commitlint/config-conventional": "^18.6.2",
"@rollup/plugin-commonjs": "^25.0.7",
@ -33,6 +35,7 @@
"@types/node": "^20.11.24",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0",
"chalk": "^4.1.0",
"eslint": "^8.57.0",
"eslint-plugin-jsdoc": "^46.10.1",
"husky": "^8.0.3",
@ -41,6 +44,7 @@
"jsdom": "^23.2.0",
"limit-size": "^0.1.4",
"lint-staged": "^15.2.2",
"lodash": "^4.17.21",
"npm-run-all": "^4.1.5",
"prettier": "^3.2.5",
"prettier-plugin-organize-imports": "^3.2.4",

View File

@ -17,5 +17,10 @@ export * from './layout-circular-division';
export * from './layout-circular-spiral';
export * from './layout-grid';
export * from './layout-mds';
export * from './layout-radial-basic';
export * from './layout-radial-configuration-translate';
export * from './layout-radial-prevent-overlap';
export * from './layout-radial-prevent-overlap-unstrict';
export * from './layout-radial-sort';
export * from './plugin-grid-line';
export * from './viewport-fit';

View File

@ -0,0 +1,29 @@
import { Graph } from '@/src';
import data from '@@/dataset/radial.json';
import type { STDTestCase } from '../types';
export const layoutRadialBasic: STDTestCase = async (context) => {
const graph = new Graph({
...context,
data,
layout: {
type: 'radial',
unitRadius: 50,
},
node: {
style: {
labelText: (d: { id: string }) => d.id,
labelPlacement: 'center',
size: 20,
fill: '#EFF4FF',
lineWidth: 1,
stroke: '#5F95FF',
},
},
behaviors: ['drag-canvas', 'drag-node'],
});
await graph.render();
return graph;
};

View File

@ -0,0 +1,38 @@
import { Graph } from '@/src';
import data from '@@/dataset/radial.json';
import type { STDTestCase } from '../types';
export const layoutRadialConfigurationTranslate: STDTestCase = async (context) => {
const graph = new Graph({
...context,
data,
layout: {
type: 'radial',
unitRadius: 50,
},
node: {
style: {
labelText: (d: { id: string }) => d.id,
labelPlacement: 'center',
size: 20,
fill: '#EFF4FF',
lineWidth: 1,
stroke: '#5F95FF',
},
},
edge: {
style: {
endArrow: {
path: 'M 0,0 L 8,4 L 8,-4 Z',
fill: '#e2e2e2',
},
},
},
behaviors: ['drag-canvas', 'drag-node'],
animation: true,
});
await graph.render();
return graph;
};

View File

@ -0,0 +1,39 @@
import { Graph } from '@/src';
import data from '@@/dataset/radial.json';
import type { STDTestCase } from '../types';
export const layoutRadialPreventOverlapUnstrict: STDTestCase = async (context) => {
const graph = new Graph({
...context,
data,
layout: {
type: 'radial',
unitRadius: 70,
preventOverlap: true,
strictRadial: false,
},
node: {
style: {
labelText: (d: { id: string }) => d.id,
labelPlacement: 'center',
size: 20,
fill: '#EFF4FF',
lineWidth: 1,
stroke: '#5F95FF',
},
},
edge: {
style: {
endArrow: {
path: 'M 0,0 L 8,4 L 8,-4 Z',
fill: '#e2e2e2',
},
},
},
behaviors: ['drag-canvas', 'drag-node'],
});
await graph.render();
return graph;
};

View File

@ -0,0 +1,39 @@
import { Graph } from '@/src';
import data from '@@/dataset/radial.json';
import type { STDTestCase } from '../types';
export const layoutRadialPreventOverlap: STDTestCase = async (context) => {
const graph = new Graph({
...context,
data,
layout: {
type: 'radial',
unitRadius: 50,
preventOverlap: true,
maxPreventOverlapIteration: 100,
},
node: {
style: {
labelText: (d: { id: string }) => d.id,
labelPlacement: 'center',
size: 20,
fill: '#EFF4FF',
lineWidth: 1,
stroke: '#5F95FF',
},
},
edge: {
style: {
endArrow: {
path: 'M 0,0 L 8,4 L 8,-4 Z',
fill: '#e2e2e2',
},
},
},
behaviors: ['drag-canvas', 'drag-node'],
});
await graph.render();
return graph;
};

View File

@ -0,0 +1,43 @@
import { Graph } from '@/src';
import data from '@@/dataset/radial.json';
import type { STDTestCase } from '../types';
export const layoutRadialSort: STDTestCase = async (context) => {
const graph = new Graph({
...context,
data,
layout: {
type: 'radial',
unitRadius: 70,
maxIteration: 1000,
linkDistance: 10,
preventOverlap: true,
nodeSize: 30,
sortBy: 'sortAttr2',
sortStrength: 50,
},
node: {
style: {
labelText: (d: { id: string }) => d.id,
labelPlacement: 'center',
size: 20,
fill: '#EFF4FF',
lineWidth: 1,
stroke: '#5F95FF',
},
},
edge: {
style: {
endArrow: {
path: 'M 0,0 L 8,4 L 8,-4 Z',
fill: '#e2e2e2',
},
},
},
behaviors: ['drag-canvas', 'drag-node'],
});
await graph.render();
return graph;
};

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 93 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 141 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 142 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 142 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 142 KiB

View File

@ -0,0 +1,40 @@
import {
layoutRadialBasic,
layoutRadialConfigurationTranslate,
layoutRadialPreventOverlap,
layoutRadialPreventOverlapUnstrict,
layoutRadialSort,
} from '@@/demo/case';
import { createDemoGraph } from '@@/utils';
describe('radial layout', () => {
it('basic', async () => {
const graph = await createDemoGraph(layoutRadialBasic);
await expect(graph).toMatchSnapshot(__filename, 'basic');
graph.destroy();
});
it('configuration translate', async () => {
const graph = await createDemoGraph(layoutRadialConfigurationTranslate);
await expect(graph).toMatchSnapshot(__filename, 'configuration-translate');
graph.destroy();
});
it('prevent overlap', async () => {
const graph = await createDemoGraph(layoutRadialPreventOverlap);
await expect(graph).toMatchSnapshot(__filename, 'prevent-overlap');
graph.destroy();
});
it('prevent overlap unstrict', async () => {
const graph = await createDemoGraph(layoutRadialPreventOverlapUnstrict);
await expect(graph).toMatchSnapshot(__filename, 'prevent-overlap-unstrict');
graph.destroy();
});
it('sort', async () => {
const graph = await createDemoGraph(layoutRadialSort);
await expect(graph).toMatchSnapshot(__filename, 'sort');
graph.destroy();
});
});

View File

@ -438,10 +438,10 @@ const time = setInterval(function () {
* @param layoutConfig
*/
function updateLayout(layoutConfig) {
graph.setLayout({
type: 'circular',
graph.setLayout((current) => ({
...current,
...layoutConfig,
});
}));
graph.render();
}

View File

@ -393,7 +393,7 @@ const graph = new Graph({
node: {
style: {
size: 20,
labelText: (d: { id: string }) => d.id,
labelText: (d) => d.id,
fill: '#EFF4FF',
lineWidth: 1,
stroke: '#5F95FF',

View File

@ -0,0 +1,406 @@
import { Graph } from '@antv/g6';
const data = {
nodes: [
{
id: '0',
label: '0',
},
{
id: '1',
label: '1',
},
{
id: '2',
label: '2',
},
{
id: '3',
label: '3',
},
{
id: '4',
label: '4',
},
{
id: '5',
label: '5',
},
{
id: '6',
label: '6',
},
{
id: '7',
label: '7',
},
{
id: '8',
label: '8',
},
{
id: '9',
label: '9',
},
{
id: '10',
label: '10',
},
{
id: '11',
label: '11',
},
{
id: '12',
label: '12',
},
{
id: '13',
label: '13',
},
{
id: '14',
label: '14',
},
{
id: '15',
label: '15',
},
{
id: '16',
label: '16',
},
{
id: '17',
label: '17',
},
{
id: '18',
label: '18',
},
{
id: '19',
label: '19',
},
{
id: '20',
label: '20',
},
{
id: '21',
label: '21',
},
{
id: '22',
label: '22',
},
{
id: '23',
label: '23',
},
{
id: '24',
label: '24',
},
{
id: '25',
label: '25',
},
{
id: '26',
label: '26',
},
{
id: '27',
label: '27',
},
{
id: '28',
label: '28',
},
{
id: '29',
label: '29',
},
{
id: '30',
label: '30',
},
{
id: '31',
label: '31',
},
{
id: '32',
label: '32',
},
{
id: '33',
label: '33',
},
],
edges: [
{
source: '0',
target: '1',
},
{
source: '0',
target: '2',
},
{
source: '0',
target: '3',
},
{
source: '0',
target: '4',
},
{
source: '0',
target: '5',
},
{
source: '0',
target: '7',
},
{
source: '0',
target: '8',
},
{
source: '0',
target: '9',
},
{
source: '0',
target: '10',
},
{
source: '0',
target: '11',
},
{
source: '0',
target: '13',
},
{
source: '0',
target: '14',
},
{
source: '0',
target: '15',
},
{
source: '0',
target: '16',
},
{
source: '2',
target: '3',
},
{
source: '4',
target: '5',
},
{
source: '4',
target: '6',
},
{
source: '5',
target: '6',
},
{
source: '7',
target: '13',
},
{
source: '8',
target: '14',
},
{
source: '9',
target: '10',
},
{
source: '10',
target: '22',
},
{
source: '10',
target: '14',
},
{
source: '10',
target: '12',
},
{
source: '10',
target: '24',
},
{
source: '10',
target: '21',
},
{
source: '10',
target: '20',
},
{
source: '11',
target: '24',
},
{
source: '11',
target: '22',
},
{
source: '11',
target: '14',
},
{
source: '12',
target: '13',
},
{
source: '16',
target: '17',
},
{
source: '16',
target: '18',
},
{
source: '16',
target: '21',
},
{
source: '16',
target: '22',
},
{
source: '17',
target: '18',
},
{
source: '17',
target: '20',
},
{
source: '18',
target: '19',
},
{
source: '19',
target: '20',
},
{
source: '19',
target: '33',
},
{
source: '19',
target: '22',
},
{
source: '19',
target: '23',
},
{
source: '20',
target: '21',
},
{
source: '21',
target: '22',
},
{
source: '22',
target: '24',
},
{
source: '22',
target: '25',
},
{
source: '22',
target: '26',
},
{
source: '22',
target: '23',
},
{
source: '22',
target: '28',
},
{
source: '22',
target: '30',
},
{
source: '22',
target: '31',
},
{
source: '22',
target: '32',
},
{
source: '22',
target: '33',
},
{
source: '23',
target: '28',
},
{
source: '23',
target: '27',
},
{
source: '23',
target: '29',
},
{
source: '23',
target: '30',
},
{
source: '23',
target: '31',
},
{
source: '23',
target: '33',
},
{
source: '32',
target: '33',
},
],
};
const graph = new Graph({
container: 'container',
data,
layout: {
type: 'radial',
unitRadius: 50,
},
node: {
style: {
labelText: (d) => d.id,
labelPlacement: 'center',
size: 20,
fill: '#EFF4FF',
lineWidth: 1,
stroke: '#5F95FF',
},
},
behaviors: ['drag-canvas', 'drag-node'],
});
graph.render();

View File

@ -1,516 +1,382 @@
import { Graph, Extensions, extend } from '@antv/g6';
const ExtGraph = extend(Graph, {
layouts: {
radial: Extensions.RadialLayout,
},
});
import { Graph } from '@antv/g6';
const data = {
nodes: [
{
id: '0',
data: {
label: '0',
},
label: '0',
},
{
id: '1',
data: {
label: '1',
},
label: '1',
},
{
id: '2',
data: {
label: '2',
},
label: '2',
},
{
id: '3',
data: {
label: '3',
},
label: '3',
},
{
id: '4',
data: {
label: '4',
},
label: '4',
},
{
id: '5',
data: {
label: '5',
},
label: '5',
},
{
id: '6',
data: {
label: '6',
},
label: '6',
},
{
id: '7',
data: {
label: '7',
},
label: '7',
},
{
id: '8',
data: {
label: '8',
},
label: '8',
},
{
id: '9',
data: {
label: '9',
},
label: '9',
},
{
id: '10',
data: {
label: '10',
},
label: '10',
},
{
id: '11',
data: {
label: '11',
},
label: '11',
},
{
id: '12',
data: {
label: '12',
},
label: '12',
},
{
id: '13',
data: {
label: '13',
},
label: '13',
},
{
id: '14',
data: {
label: '14',
},
label: '14',
},
{
id: '15',
data: {
label: '15',
},
label: '15',
},
{
id: '16',
data: {
label: '16',
},
label: '16',
},
{
id: '17',
data: {
label: '17',
},
label: '17',
},
{
id: '18',
data: {
label: '18',
},
label: '18',
},
{
id: '19',
data: {
label: '19',
},
label: '19',
},
{
id: '20',
data: {
label: '20',
},
label: '20',
},
{
id: '21',
data: {
label: '21',
},
label: '21',
},
{
id: '22',
data: {
label: '22',
},
label: '22',
},
{
id: '23',
data: {
label: '23',
},
label: '23',
},
{
id: '24',
data: {
label: '24',
},
label: '24',
},
{
id: '25',
data: {
label: '25',
},
label: '25',
},
{
id: '26',
data: {
label: '26',
},
label: '26',
},
{
id: '27',
data: {
label: '27',
},
label: '27',
},
{
id: '28',
data: {
label: '28',
},
label: '28',
},
{
id: '29',
data: {
label: '29',
},
label: '29',
},
{
id: '30',
data: {
label: '30',
},
label: '30',
},
{
id: '31',
data: {
label: '31',
},
label: '31',
},
{
id: '32',
data: {
label: '32',
},
label: '32',
},
{
id: '33',
data: {
label: '33',
},
label: '33',
},
],
edges: [
{
id: 'edge-841',
source: '0',
target: '1',
},
{
id: 'edge-655',
source: '0',
target: '2',
},
{
id: 'edge-404',
source: '0',
target: '3',
},
{
id: 'edge-601',
source: '0',
target: '4',
},
{
id: 'edge-554',
source: '0',
target: '5',
},
{
id: 'edge-50',
source: '0',
target: '7',
},
{
id: 'edge-369',
source: '0',
target: '8',
},
{
id: 'edge-239',
source: '0',
target: '9',
},
{
id: 'edge-475',
source: '0',
target: '10',
},
{
id: 'edge-342',
source: '0',
target: '11',
},
{
id: 'edge-63',
source: '0',
target: '13',
},
{
id: 'edge-26',
source: '0',
target: '14',
},
{
id: 'edge-33',
source: '0',
target: '15',
},
{
id: 'edge-867',
source: '0',
target: '16',
},
{
id: 'edge-620',
source: '2',
target: '3',
},
{
id: 'edge-843',
source: '4',
target: '5',
},
{
id: 'edge-832',
source: '4',
target: '6',
},
{
id: 'edge-157',
source: '5',
target: '6',
},
{
id: 'edge-48',
source: '7',
target: '13',
},
{
id: 'edge-114',
source: '8',
target: '14',
},
{
id: 'edge-912',
source: '9',
target: '10',
},
{
id: 'edge-494',
source: '10',
target: '22',
},
{
id: 'edge-960',
source: '10',
target: '14',
},
{
id: 'edge-384',
source: '10',
target: '12',
},
{
id: 'edge-94',
source: '10',
target: '24',
},
{
id: 'edge-361',
source: '10',
target: '21',
},
{
id: 'edge-299',
source: '10',
target: '20',
},
{
id: 'edge-645',
source: '11',
target: '24',
},
{
id: 'edge-487',
source: '11',
target: '22',
},
{
id: 'edge-622',
source: '11',
target: '14',
},
{
id: 'edge-21',
source: '12',
target: '13',
},
{
id: 'edge-286',
source: '16',
target: '17',
},
{
id: 'edge-643',
source: '16',
target: '18',
},
{
id: 'edge-306',
source: '16',
target: '21',
},
{
id: 'edge-45',
source: '16',
target: '22',
},
{
id: 'edge-912',
source: '17',
target: '18',
},
{
id: 'edge-820',
source: '17',
target: '20',
},
{
id: 'edge-399',
source: '18',
target: '19',
},
{
id: 'edge-186',
source: '19',
target: '20',
},
{
id: 'edge-220',
source: '19',
target: '33',
},
{
id: 'edge-577',
source: '19',
target: '22',
},
{
id: 'edge-191',
source: '19',
target: '23',
},
{
id: 'edge-390',
source: '20',
target: '21',
},
{
id: 'edge-304',
source: '21',
target: '22',
},
{
id: 'edge-888',
source: '22',
target: '24',
},
{
id: 'edge-795',
source: '22',
target: '25',
},
{
id: 'edge-716',
source: '22',
target: '26',
},
{
id: 'edge-100',
source: '22',
target: '23',
},
{
id: 'edge-933',
source: '22',
target: '28',
},
{
id: 'edge-193',
source: '22',
target: '30',
},
{
id: 'edge-748',
source: '22',
target: '31',
},
{
id: 'edge-176',
source: '22',
target: '32',
},
{
id: 'edge-525',
source: '22',
target: '33',
},
{
id: 'edge-795',
source: '23',
target: '28',
},
{
id: 'edge-311',
source: '23',
target: '27',
},
{
id: 'edge-499',
source: '23',
target: '29',
},
{
id: 'edge-418',
source: '23',
target: '30',
},
{
id: 'edge-409',
source: '23',
target: '31',
},
{
id: 'edge-426',
source: '23',
target: '33',
},
{
id: 'edge-876',
source: '32',
target: '33',
},
@ -519,56 +385,76 @@ const data = {
const descriptionDiv = document.createElement('div');
descriptionDiv.innerHTML = 'Radial layout, focusNode = = 0, unitRadius = 50, preventOverlap: false';
const container = document.getElementById('container');
const container = document.getElementById('container') as HTMLDivElement;
container.appendChild(descriptionDiv);
const width = container.scrollWidth;
const height = (container.scrollHeight || 500) - 20;
const graph = new ExtGraph({
const graph = new Graph({
container: 'container',
width,
height,
modes: {
default: ['drag-canvas', 'drag-node', 'zoom-canvas', 'click-select'],
},
layout: {
type: 'radial',
unitRadius: 50,
},
animate: true,
defaultNode: {
size: 20,
data,
node: {
style: {
labelText: (d) => d.id,
labelPlacement: 'center',
size: 20,
fill: '#EFF4FF',
lineWidth: 1,
stroke: '#5F95FF',
},
},
edge: {
keyShape: {
endArrow: true,
style: {
endArrow: {
path: 'M 0,0 L 8,4 L 8,-4 Z',
fill: '#e2e2e2',
},
},
},
node: {
animates: {
update: [
{
fields: ['x', 'y'],
},
],
},
},
data,
behaviors: ['drag-canvas', 'drag-node'],
animation: true,
});
graph.render();
if (typeof window !== 'undefined') {
window.addEventListener('error', () => {
if (time) {
clearInterval(time);
}
});
window.onresize = () => {
if (!graph || graph.destroyed) return;
if (!container || !container.scrollWidth || !container.scrollHeight) return;
graph.resize(container.scrollWidth, container.scrollHeight - 30);
};
}
window.graph = graph;
layoutConfigTranslation();
setInterval(function () {
const time = setInterval(function () {
layoutConfigTranslation();
}, 7000);
}, 11500);
/**
*
* @param layoutConfig
*/
function updateLayout(layoutConfig) {
graph.setLayout((current) => ({
...current,
...layoutConfig,
}));
graph.render();
}
/**
*
*/
function layoutConfigTranslation() {
setTimeout(function () {
descriptionDiv.innerHTML = 'Radial layout, focusNode = = 0, unitRadius = 50, preventOverlap: true';
graph.layout({
type: 'radial',
updateLayout({
preventOverlap: true,
nodeSize: 20,
});
@ -576,32 +462,28 @@ function layoutConfigTranslation() {
setTimeout(function () {
descriptionDiv.innerHTML = 'Radial layout, focusNode = = 0, unitRadius = 80, preventOverlap: true';
graph.layout({
type: 'radial',
updateLayout({
unitRadius: 80,
});
}, 2500);
setTimeout(function () {
descriptionDiv.innerHTML = 'Radial layout, focusNode = = 10, unitRadius = 80, preventOverlap: true';
graph.layout({
type: 'radial',
updateLayout({
focusNode: '10',
});
}, 4000);
setTimeout(function () {
descriptionDiv.innerHTML = 'Radial layout, focusNode = = 20, unitRadius = 80, preventOverlap: true';
graph.layout({
type: 'radial',
updateLayout({
focusNode: '20',
});
}, 5500);
setTimeout(function () {
descriptionDiv.innerHTML = 'Radial layout, focusNode = = 0, unitRadius = 50, preventOverlap: false';
graph.layout({
type: 'radial',
updateLayout({
focusNode: '0',
preventOverlap: false,
unitRadius: 50,

View File

@ -1,997 +0,0 @@
// TODO: skip this demo sincle sub layout is wrong for this demo
import { Graph, Extensions, extend } from '@antv/g6';
import { Graph as GraphCore } from '@antv/graphlib';
const ExtGraph = extend(Graph, {
layouts: {
radial: Extensions.RadialLayout,
},
});
const data = {
nodes: [
{
id: '0',
data: {
label: '0',
},
},
{
id: '1',
data: {
label: '1',
},
},
{
id: '2',
data: {
label: '2',
},
},
{
id: '3',
data: {
label: '3',
},
},
{
id: '4',
data: {
label: '4',
},
},
{
id: '5',
data: {
label: '5',
},
},
{
id: '6',
data: {
label: '6',
},
},
{
id: '7',
data: {
label: '7',
},
},
{
id: '8',
data: {
label: '8',
},
},
{
id: '9',
data: {
label: '9',
},
},
{
id: '10',
data: {
label: '10',
},
},
{
id: '11',
data: {
label: '11',
},
},
{
id: '12',
data: {
label: '12',
},
},
{
id: '13',
data: {
label: '13',
},
},
{
id: '14',
data: {
label: '14',
},
},
{
id: '15',
data: {
label: '15',
},
},
{
id: '16',
data: {
label: '16',
},
},
{
id: '17',
data: {
label: '17',
},
},
{
id: '18',
data: {
label: '18',
},
},
{
id: '19',
data: {
label: '19',
},
},
{
id: '20',
data: {
label: '20',
},
},
{
id: '21',
data: {
label: '21',
},
},
{
id: '22',
data: {
label: '22',
},
},
{
id: '23',
data: {
label: '23',
},
},
{
id: '24',
data: {
label: '24',
},
},
{
id: '25',
data: {
label: '25',
},
},
{
id: '26',
data: {
label: '26',
},
},
{
id: '27',
data: {
label: '27',
},
},
{
id: '28',
data: {
label: '28',
},
},
{
id: '29',
data: {
label: '29',
},
},
{
id: '30',
data: {
label: '30',
},
},
{
id: '31',
data: {
label: '31',
},
},
{
id: '32',
data: {
label: '32',
},
},
{
id: '33',
data: {
label: '33',
},
},
],
edges: [
{
id: 'edge-841',
source: '0',
target: '1',
},
{
id: 'edge-655',
source: '0',
target: '2',
},
{
id: 'edge-404',
source: '0',
target: '3',
},
{
id: 'edge-601',
source: '0',
target: '4',
},
{
id: 'edge-554',
source: '0',
target: '5',
},
{
id: 'edge-50',
source: '0',
target: '7',
},
{
id: 'edge-369',
source: '0',
target: '8',
},
{
id: 'edge-239',
source: '0',
target: '9',
},
{
id: 'edge-475',
source: '0',
target: '10',
},
{
id: 'edge-342',
source: '0',
target: '11',
},
{
id: 'edge-63',
source: '0',
target: '13',
},
{
id: 'edge-26',
source: '0',
target: '14',
},
{
id: 'edge-33',
source: '0',
target: '15',
},
{
id: 'edge-867',
source: '0',
target: '16',
},
{
id: 'edge-620',
source: '2',
target: '3',
},
{
id: 'edge-843',
source: '4',
target: '5',
},
{
id: 'edge-832',
source: '4',
target: '6',
},
{
id: 'edge-157',
source: '5',
target: '6',
},
{
id: 'edge-48',
source: '7',
target: '13',
},
{
id: 'edge-114',
source: '8',
target: '14',
},
{
id: 'edge-913',
source: '9',
target: '10',
},
{
id: 'edge-494',
source: '10',
target: '22',
},
{
id: 'edge-960',
source: '10',
target: '14',
},
{
id: 'edge-384',
source: '10',
target: '12',
},
{
id: 'edge-94',
source: '10',
target: '24',
},
{
id: 'edge-361',
source: '10',
target: '21',
},
{
id: 'edge-299',
source: '10',
target: '20',
},
{
id: 'edge-645',
source: '11',
target: '24',
},
{
id: 'edge-487',
source: '11',
target: '22',
},
{
id: 'edge-622',
source: '11',
target: '14',
},
{
id: 'edge-21',
source: '12',
target: '13',
},
{
id: 'edge-286',
source: '16',
target: '17',
},
{
id: 'edge-643',
source: '16',
target: '18',
},
{
id: 'edge-306',
source: '16',
target: '21',
},
{
id: 'edge-45',
source: '16',
target: '22',
},
{
id: 'edge-912',
source: '17',
target: '18',
},
{
id: 'edge-820',
source: '17',
target: '20',
},
{
id: 'edge-399',
source: '18',
target: '19',
},
{
id: 'edge-186',
source: '19',
target: '20',
},
{
id: 'edge-220',
source: '19',
target: '33',
},
{
id: 'edge-577',
source: '19',
target: '22',
},
{
id: 'edge-191',
source: '19',
target: '23',
},
{
id: 'edge-390',
source: '20',
target: '21',
},
{
id: 'edge-304',
source: '21',
target: '22',
},
{
id: 'edge-888',
source: '22',
target: '24',
},
{
id: 'edge-796',
source: '22',
target: '25',
},
{
id: 'edge-716',
source: '22',
target: '26',
},
{
id: 'edge-100',
source: '22',
target: '23',
},
{
id: 'edge-933',
source: '22',
target: '28',
},
{
id: 'edge-193',
source: '22',
target: '30',
},
{
id: 'edge-748',
source: '22',
target: '31',
},
{
id: 'edge-176',
source: '22',
target: '32',
},
{
id: 'edge-525',
source: '22',
target: '33',
},
{
id: 'edge-795',
source: '23',
target: '28',
},
{
id: 'edge-311',
source: '23',
target: '27',
},
{
id: 'edge-499',
source: '23',
target: '29',
},
{
id: 'edge-418',
source: '23',
target: '30',
},
{
id: 'edge-409',
source: '23',
target: '31',
},
{
id: 'edge-426',
source: '23',
target: '33',
},
{
id: 'edge-876',
source: '32',
target: '33',
},
],
};
const data2_m = {
nodes: [
{
id: '2',
data: {
label: '2',
},
},
{
id: '1001',
data: {
label: '1001',
},
},
{
id: '1002',
data: {
label: '1002',
},
},
{
id: '1003',
data: {
label: '1003',
},
},
{
id: '1004',
data: {
label: '1004',
},
},
{
id: '1005',
data: {
label: '1005',
},
},
{
id: '1006',
data: {
label: '1006',
},
},
{
id: '1007',
data: {
label: '1007',
},
},
{
id: '1008',
data: {
label: '1008',
},
},
{
id: '1009',
data: {
label: '1009',
},
},
{
id: '1010',
data: {
label: '1010',
},
},
{
id: '1011',
data: {
label: '1011',
},
},
{
id: '1012',
data: {
label: '1012',
},
},
{
id: '1013',
data: {
label: '1013',
},
},
{
id: '1014',
data: {
label: '1014',
},
},
{
id: '1015',
data: {
label: '1015',
},
},
{
id: '1016',
data: {
label: '1016',
},
},
{
id: '1017',
data: {
label: '1017',
},
},
{
id: '1018',
data: {
label: '1018',
},
},
{
id: '1019',
data: {
label: '1019',
},
},
{
id: '1020',
data: {
label: '1020',
},
},
{
id: '5',
data: {
label: '5',
},
},
{
id: '41',
data: {
label: '41',
},
},
],
edges: [
{
id: 'edge-313',
source: '2',
target: '1001',
},
{
id: 'edge-891',
source: '2',
target: '1002',
},
{
id: 'edge-478',
source: '2',
target: '1003',
},
{
id: 'edge-250',
source: '2',
target: '1004',
},
{
id: 'edge-535',
source: '2',
target: '1005',
},
{
id: 'edge-850',
source: '1001',
target: '1006',
},
{
id: 'edge-381',
source: '1001',
target: '1007',
},
{
id: 'edge-209',
source: '1001',
target: '1008',
},
{
id: 'edge-162',
source: '1001',
target: '1009',
},
{
id: 'edge-365',
source: '1001',
target: '1010',
},
{
id: 'edge-873',
source: '1002',
target: '1006',
},
{
id: 'edge-266',
source: '1002',
target: '1007',
},
{
id: 'edge-111',
source: '1002',
target: '1008',
},
{
id: 'edge-424',
source: '1002',
target: '1009',
},
{
id: 'edge-471',
source: '1002',
target: '1010',
},
{
id: 'edge-506',
source: '1003',
target: '1006',
},
{
id: 'edge-345',
source: '1003',
target: '1007',
},
{
id: 'edge-38',
source: '1003',
target: '1008',
},
{
id: 'edge-195',
source: '1003',
target: '1009',
},
{
id: 'edge-613',
source: '1003',
target: '1010',
},
{
id: 'edge-841',
source: '1010',
target: '1011',
},
{
id: 'edge-505',
source: '1010',
target: '1012',
},
{
id: 'edge-828',
source: '1010',
target: '1013',
},
{
id: 'edge-881',
source: '1010',
target: '1014',
},
{
id: 'edge-278',
source: '1010',
target: '1015',
},
{
id: 'edge-343',
source: '1010',
target: '1016',
},
{
id: 'edge-921',
source: '1010',
target: '1017',
},
{
id: 'edge-198',
source: '1008',
target: '1014',
},
{
id: 'edge-900',
source: '1008',
target: '1015',
},
{
id: 'edge-798',
source: '1008',
target: '1016',
},
{
id: 'edge-765',
source: '1008',
target: '1017',
},
{
id: 'edge-389',
source: '1017',
target: '1018',
},
{
id: 'edge-590',
source: '1017',
target: '1019',
},
{
id: 'edge-915',
source: '1016',
target: '1020',
},
{
id: 'edge-439',
source: '1016',
target: '1020',
},
{
id: 'edge-462',
source: '5',
target: '1020',
},
{
id: 'edge-641',
source: '41',
target: '1020',
},
{
id: 'edge-922',
source: '5',
target: '1009',
},
{
id: 'edge-700',
source: '41',
target: '1009',
},
],
};
const container = document.getElementById('container');
const descriptionDiv = document.createElement('div');
descriptionDiv.innerHTML = 'Try to click node 2!';
container.appendChild(descriptionDiv);
const width = container.scrollWidth;
const height = (container.scrollHeight || 500) - 30;
const mainUnitRadius = 80;
const focusNode = data.nodes[22];
focusNode.data.keyShape = {
stroke: '#00419F',
fill: '#729FFC',
lineWidth: 2,
};
data.nodes[2].data.keyShape = {
stroke: '#00419F',
fill: '#729FFC',
lineWidth: 2,
};
const graph = new ExtGraph({
container: 'container',
width,
height,
layout: {
type: 'radial',
maxIteration: 200,
focusNode,
unitRadius: mainUnitRadius,
linkDistance: 100,
preventOverlap: true,
nodeSize: 20,
},
animate: true,
modes: {
default: ['drag-canvas', 'drag-node', 'zoom-canvas', 'click-select'],
},
data,
});
graph.on('node:click', async (ev) => {
const nodeModel = graph.getNodeData(ev.itemId);
const nodes = graph.getAllNodesData();
const edges = graph.getAllEdgesData();
let newData;
if (nodeModel.id === '2') newData = data2_m;
else return;
const newNodeModels = newData.nodes;
const newEdgeModels = [];
// deduplication the items in newEdgeModels
newData.edges.forEach(function (e) {
let exist = false;
newEdgeModels.forEach(function (ne) {
if (ne.source === e.source && ne.target === e.target) exist = true;
});
if (!exist) {
newEdgeModels.push(e);
}
});
// for graph.changeData()
const allNodeModels = [],
allEdgeModels = [];
// add new nodes to graph
const nodeMap = new Map();
nodes.forEach((n) => {
nodeMap.set(n.id, n);
});
newNodeModels.forEach((model) => {
if (!nodeMap.has(model.id)) {
// set the initial positions of the new nodes to the focus(clicked) node
model.data.x = nodeModel.data.x;
model.data.y = nodeModel.data.y;
}
});
graph.addData('node', newNodeModels);
// add new edges to graph
const edgeMap = new Map();
edges.forEach(function (e, i) {
edgeMap.set(e.source + ',' + e.target, i);
});
const oldEdgeNum = edges.length;
newEdgeModels.forEach(function (em, i) {
const exist = edgeMap.get(em.source + ',' + em.target);
if (exist === undefined) {
edgeMap.set(em.source + ',' + em.target, oldEdgeNum + i);
}
});
graph.addData('edge', newEdgeModels);
edges.forEach((e) => {
allEdgeModels.push(e);
});
nodes.forEach((n) => {
allNodeModels.push(n);
});
// the max degree about foces(clicked) node in the newly added data
const maxDegree = 4;
// the max degree about foces(clicked) node in the original data
const oMaxDegree = 3;
const unitRadius = 40;
// re-place the clicked node far away the exisiting items
// along the radius from center node to it
const focus = graph.getNodeData(focusNode.id);
const vx = nodeModel.data.x - focus.data.x;
const vy = nodeModel.data.y - focus.data.y;
const vlength = Math.sqrt(vx * vx + vy * vy);
const ideallength = unitRadius * maxDegree + mainUnitRadius * oMaxDegree;
nodeModel.data.x = (ideallength * vx) / vlength + focus.data.x;
nodeModel.data.y = (ideallength * vy) / vlength + focus.data.y;
const subRadialLayout = new Extensions.RadialLayout({
center: [nodeModel.data.x, nodeModel.data.y],
maxIteration: 200,
focusNode: '2',
unitRadius,
linkDistance: 180,
preventOverlap: true,
});
const positions = await subRadialLayout.execute(
new GraphCore({
nodes: newNodeModels,
edges: newEdgeModels,
}),
);
console.log('positions', positions);
graph.updateNodePosition(positions.nodes.filter((node) => nodeMap.has(node.id)));
});
graph.on('click', (e) => {
console.log('canvas', e.canvas);
});
window.graph = graph;

View File

@ -5,44 +5,44 @@
},
"demos": [
{
"filename": "basicRadial.js",
"filename": "basic.ts",
"title": {
"zh": "基本 Radial 辐射布局",
"en": "Basic Radial Layout"
},
"screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*DQBoTocVv_EAAAAAAAAAAAAADmJ7AQ/original"
"screenshot": "https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*Ec_WQ5hqVsgAAAAAAAAAAABkARQnAQ"
},
{
"filename": "preventOverlapRadial.js",
"filename": "preventOverlap.ts",
"title": {
"zh": "防止节点重叠的严格辐射布局",
"en": "Prevent Node Overlappings and Restrict Radial"
},
"screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*Wed9QJCrM9cAAAAAAAAAAAAADmJ7AQ/original"
"screenshot": "https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*GAFjRJeAoAsAAAAAAAAAAABkARQnAQ"
},
{
"filename": "preventOverlapUnstrictRadial.js",
"filename": "preventOverlapUnstrict.ts",
"title": {
"zh": "防止节点重叠的非严格辐射布局",
"en": "Prevent Node Overlappings and Unrestrict Radial"
},
"screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*fonYTKm_WHEAAAAAAAAAAAAADmJ7AQ/original"
"screenshot": "https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*X8rzTZyWwUcAAAAAAAAAAABkARQnAQ"
},
{
"filename": "radialConfigurationTranslate.js",
"filename": "configurationTranslate.ts",
"title": {
"zh": "Radial 布局参数动态变化",
"en": "Update Configurations for Radial"
},
"screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*gbAITpEBjsIAAAAAAAAAAAAADmJ7AQ/original"
"screenshot": "https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*ikctQb9KECAAAAAAAAAAAABkARQnAQ"
},
{
"filename": "sortRadial.js",
"filename": "sort.ts",
"title": {
"zh": "同层节点按照指定字段聚类",
"en": "Order the Level Nodes"
},
"screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*7DfvS4QOjycAAAAAAAAAAAAADmJ7AQ/original"
"screenshot": "https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*gzfTQKBB62IAAAAAAAAAAABkARQnAQ"
}
]
}

View File

@ -1,545 +1,416 @@
import { Graph, Extensions, extend } from '@antv/g6';
const ExtGraph = extend(Graph, {
layouts: {
radial: Extensions.RadialLayout,
},
});
import { Graph } from '@antv/g6';
const data = {
nodes: [
{
id: '0',
data: {
label: '0',
},
label: '0',
},
{
id: '1',
data: {
label: '1',
},
label: '1',
},
{
id: '2',
data: {
label: '2',
},
label: '2',
},
{
id: '3',
data: {
label: '3',
},
label: '3',
},
{
id: '4',
data: {
label: '4',
},
label: '4',
},
{
id: '5',
data: {
label: '5',
},
label: '5',
},
{
id: '6',
data: {
label: '6',
},
label: '6',
},
{
id: '7',
data: {
label: '7',
},
label: '7',
},
{
id: '8',
data: {
label: '8',
},
label: '8',
},
{
id: '9',
data: {
label: '9',
},
label: '9',
},
{
id: '10',
data: {
label: '10',
},
label: '10',
},
{
id: '11',
data: {
label: '11',
},
label: '11',
},
{
id: '12',
data: {
label: '12',
},
label: '12',
},
{
id: '13',
data: {
label: '13',
},
label: '13',
},
{
id: '14',
data: {
label: '14',
},
label: '14',
},
{
id: '15',
data: {
label: '15',
},
label: '15',
},
{
id: '16',
data: {
label: '16',
},
label: '16',
},
{
id: '17',
data: {
label: '17',
},
label: '17',
},
{
id: '18',
data: {
label: '18',
},
label: '18',
},
{
id: '19',
data: {
label: '19',
},
label: '19',
},
{
id: '20',
data: {
label: '20',
},
label: '20',
},
{
id: '21',
data: {
label: '21',
},
label: '21',
},
{
id: '22',
data: {
label: '22',
},
label: '22',
},
{
id: '23',
data: {
label: '23',
},
label: '23',
},
{
id: '24',
data: {
label: '24',
},
label: '24',
},
{
id: '25',
data: {
label: '25',
},
label: '25',
},
{
id: '26',
data: {
label: '26',
},
label: '26',
},
{
id: '27',
data: {
label: '27',
},
label: '27',
},
{
id: '28',
data: {
label: '28',
},
label: '28',
},
{
id: '29',
data: {
label: '29',
},
label: '29',
},
{
id: '30',
data: {
label: '30',
},
label: '30',
},
{
id: '31',
data: {
label: '31',
},
label: '31',
},
{
id: '32',
data: {
label: '32',
},
label: '32',
},
{
id: '33',
data: {
label: '33',
},
label: '33',
},
],
edges: [
{
id: 'edge-841',
source: '0',
target: '1',
},
{
id: 'edge-655',
source: '0',
target: '2',
},
{
id: 'edge-404',
source: '0',
target: '3',
},
{
id: 'edge-601',
source: '0',
target: '4',
},
{
id: 'edge-554',
source: '0',
target: '5',
},
{
id: 'edge-50',
source: '0',
target: '7',
},
{
id: 'edge-369',
source: '0',
target: '8',
},
{
id: 'edge-239',
source: '0',
target: '9',
},
{
id: 'edge-475',
source: '0',
target: '10',
},
{
id: 'edge-342',
source: '0',
target: '11',
},
{
id: 'edge-63',
source: '0',
target: '13',
},
{
id: 'edge-26',
source: '0',
target: '14',
},
{
id: 'edge-33',
source: '0',
target: '15',
},
{
id: 'edge-867',
source: '0',
target: '16',
},
{
id: 'edge-620',
source: '2',
target: '3',
},
{
id: 'edge-843',
source: '4',
target: '5',
},
{
id: 'edge-832',
source: '4',
target: '6',
},
{
id: 'edge-157',
source: '5',
target: '6',
},
{
id: 'edge-48',
source: '7',
target: '13',
},
{
id: 'edge-114',
source: '8',
target: '14',
},
{
id: 'edge-912',
source: '9',
target: '10',
},
{
id: 'edge-494',
source: '10',
target: '22',
},
{
id: 'edge-960',
source: '10',
target: '14',
},
{
id: 'edge-384',
source: '10',
target: '12',
},
{
id: 'edge-94',
source: '10',
target: '24',
},
{
id: 'edge-361',
source: '10',
target: '21',
},
{
id: 'edge-299',
source: '10',
target: '20',
},
{
id: 'edge-645',
source: '11',
target: '24',
},
{
id: 'edge-487',
source: '11',
target: '22',
},
{
id: 'edge-622',
source: '11',
target: '14',
},
{
id: 'edge-21',
source: '12',
target: '13',
},
{
id: 'edge-286',
source: '16',
target: '17',
},
{
id: 'edge-643',
source: '16',
target: '18',
},
{
id: 'edge-306',
source: '16',
target: '21',
},
{
id: 'edge-45',
source: '16',
target: '22',
},
{
id: 'edge-912',
source: '17',
target: '18',
},
{
id: 'edge-820',
source: '17',
target: '20',
},
{
id: 'edge-399',
source: '18',
target: '19',
},
{
id: 'edge-186',
source: '19',
target: '20',
},
{
id: 'edge-220',
source: '19',
target: '33',
},
{
id: 'edge-577',
source: '19',
target: '22',
},
{
id: 'edge-191',
source: '19',
target: '23',
},
{
id: 'edge-390',
source: '20',
target: '21',
},
{
id: 'edge-304',
source: '21',
target: '22',
},
{
id: 'edge-888',
source: '22',
target: '24',
},
{
id: 'edge-795',
source: '22',
target: '25',
},
{
id: 'edge-716',
source: '22',
target: '26',
},
{
id: 'edge-100',
source: '22',
target: '23',
},
{
id: 'edge-933',
source: '22',
target: '28',
},
{
id: 'edge-193',
source: '22',
target: '30',
},
{
id: 'edge-748',
source: '22',
target: '31',
},
{
id: 'edge-176',
source: '22',
target: '32',
},
{
id: 'edge-525',
source: '22',
target: '33',
},
{
id: 'edge-795',
source: '23',
target: '28',
},
{
id: 'edge-311',
source: '23',
target: '27',
},
{
id: 'edge-499',
source: '23',
target: '29',
},
{
id: 'edge-418',
source: '23',
target: '30',
},
{
id: 'edge-409',
source: '23',
target: '31',
},
{
id: 'edge-426',
source: '23',
target: '33',
},
{
id: 'edge-876',
source: '32',
target: '33',
},
],
};
const container = document.getElementById('container');
const width = container.scrollWidth;
const height = container.scrollHeight || 500;
const graph = new ExtGraph({
const graph = new Graph({
container: 'container',
width,
height,
modes: {
default: ['drag-canvas', 'drag-node', 'zoom-canvas', 'click-select'],
},
data,
layout: {
type: 'radial',
unitRadius: 150,
linkDistance: 200,
unitRadius: 50,
preventOverlap: true,
maxPreventOverlapIteration: 100,
},
edge: {
keyShape: {
endArrow: true,
node: {
style: {
labelText: (d) => d.id,
labelPlacement: 'center',
size: () => Math.random() * 20 + 10,
fill: '#EFF4FF',
lineWidth: 1,
stroke: '#5F95FF',
},
},
data,
edge: {
style: {
endArrow: {
path: 'M 0,0 L 8,4 L 8,-4 Z',
fill: '#e2e2e2',
},
},
},
behaviors: ['drag-canvas', 'drag-node'],
});
window.graph = graph;
graph.render();

View File

@ -1,546 +1,416 @@
import { Graph, Extensions, extend } from '@antv/g6';
const ExtGraph = extend(Graph, {
layouts: {
radial: Extensions.RadialLayout,
},
});
import { Graph } from '@antv/g6';
const data = {
nodes: [
{
id: '0',
data: {
label: '0',
},
label: '0',
},
{
id: '1',
data: {
label: '1',
},
label: '1',
},
{
id: '2',
data: {
label: '2',
},
label: '2',
},
{
id: '3',
data: {
label: '3',
},
label: '3',
},
{
id: '4',
data: {
label: '4',
},
label: '4',
},
{
id: '5',
data: {
label: '5',
},
label: '5',
},
{
id: '6',
data: {
label: '6',
},
label: '6',
},
{
id: '7',
data: {
label: '7',
},
label: '7',
},
{
id: '8',
data: {
label: '8',
},
label: '8',
},
{
id: '9',
data: {
label: '9',
},
label: '9',
},
{
id: '10',
data: {
label: '10',
},
label: '10',
},
{
id: '11',
data: {
label: '11',
},
label: '11',
},
{
id: '12',
data: {
label: '12',
},
label: '12',
},
{
id: '13',
data: {
label: '13',
},
label: '13',
},
{
id: '14',
data: {
label: '14',
},
label: '14',
},
{
id: '15',
data: {
label: '15',
},
label: '15',
},
{
id: '16',
data: {
label: '16',
},
label: '16',
},
{
id: '17',
data: {
label: '17',
},
label: '17',
},
{
id: '18',
data: {
label: '18',
},
label: '18',
},
{
id: '19',
data: {
label: '19',
},
label: '19',
},
{
id: '20',
data: {
label: '20',
},
label: '20',
},
{
id: '21',
data: {
label: '21',
},
label: '21',
},
{
id: '22',
data: {
label: '22',
},
label: '22',
},
{
id: '23',
data: {
label: '23',
},
label: '23',
},
{
id: '24',
data: {
label: '24',
},
label: '24',
},
{
id: '25',
data: {
label: '25',
},
label: '25',
},
{
id: '26',
data: {
label: '26',
},
label: '26',
},
{
id: '27',
data: {
label: '27',
},
label: '27',
},
{
id: '28',
data: {
label: '28',
},
label: '28',
},
{
id: '29',
data: {
label: '29',
},
label: '29',
},
{
id: '30',
data: {
label: '30',
},
label: '30',
},
{
id: '31',
data: {
label: '31',
},
label: '31',
},
{
id: '32',
data: {
label: '32',
},
label: '32',
},
{
id: '33',
data: {
label: '33',
},
label: '33',
},
],
edges: [
{
id: 'edge-841',
source: '0',
target: '1',
},
{
id: 'edge-655',
source: '0',
target: '2',
},
{
id: 'edge-404',
source: '0',
target: '3',
},
{
id: 'edge-601',
source: '0',
target: '4',
},
{
id: 'edge-554',
source: '0',
target: '5',
},
{
id: 'edge-50',
source: '0',
target: '7',
},
{
id: 'edge-369',
source: '0',
target: '8',
},
{
id: 'edge-239',
source: '0',
target: '9',
},
{
id: 'edge-475',
source: '0',
target: '10',
},
{
id: 'edge-342',
source: '0',
target: '11',
},
{
id: 'edge-63',
source: '0',
target: '13',
},
{
id: 'edge-26',
source: '0',
target: '14',
},
{
id: 'edge-33',
source: '0',
target: '15',
},
{
id: 'edge-867',
source: '0',
target: '16',
},
{
id: 'edge-620',
source: '2',
target: '3',
},
{
id: 'edge-843',
source: '4',
target: '5',
},
{
id: 'edge-832',
source: '4',
target: '6',
},
{
id: 'edge-157',
source: '5',
target: '6',
},
{
id: 'edge-48',
source: '7',
target: '13',
},
{
id: 'edge-114',
source: '8',
target: '14',
},
{
id: 'edge-912',
source: '9',
target: '10',
},
{
id: 'edge-494',
source: '10',
target: '22',
},
{
id: 'edge-960',
source: '10',
target: '14',
},
{
id: 'edge-384',
source: '10',
target: '12',
},
{
id: 'edge-94',
source: '10',
target: '24',
},
{
id: 'edge-361',
source: '10',
target: '21',
},
{
id: 'edge-299',
source: '10',
target: '20',
},
{
id: 'edge-645',
source: '11',
target: '24',
},
{
id: 'edge-487',
source: '11',
target: '22',
},
{
id: 'edge-622',
source: '11',
target: '14',
},
{
id: 'edge-21',
source: '12',
target: '13',
},
{
id: 'edge-286',
source: '16',
target: '17',
},
{
id: 'edge-643',
source: '16',
target: '18',
},
{
id: 'edge-306',
source: '16',
target: '21',
},
{
id: 'edge-45',
source: '16',
target: '22',
},
{
id: 'edge-912',
source: '17',
target: '18',
},
{
id: 'edge-820',
source: '17',
target: '20',
},
{
id: 'edge-399',
source: '18',
target: '19',
},
{
id: 'edge-186',
source: '19',
target: '20',
},
{
id: 'edge-220',
source: '19',
target: '33',
},
{
id: 'edge-577',
source: '19',
target: '22',
},
{
id: 'edge-191',
source: '19',
target: '23',
},
{
id: 'edge-390',
source: '20',
target: '21',
},
{
id: 'edge-304',
source: '21',
target: '22',
},
{
id: 'edge-888',
source: '22',
target: '24',
},
{
id: 'edge-795',
source: '22',
target: '25',
},
{
id: 'edge-716',
source: '22',
target: '26',
},
{
id: 'edge-100',
source: '22',
target: '23',
},
{
id: 'edge-933',
source: '22',
target: '28',
},
{
id: 'edge-193',
source: '22',
target: '30',
},
{
id: 'edge-748',
source: '22',
target: '31',
},
{
id: 'edge-176',
source: '22',
target: '32',
},
{
id: 'edge-525',
source: '22',
target: '33',
},
{
id: 'edge-795',
source: '23',
target: '28',
},
{
id: 'edge-311',
source: '23',
target: '27',
},
{
id: 'edge-499',
source: '23',
target: '29',
},
{
id: 'edge-418',
source: '23',
target: '30',
},
{
id: 'edge-409',
source: '23',
target: '31',
},
{
id: 'edge-426',
source: '23',
target: '33',
},
{
id: 'edge-876',
source: '32',
target: '33',
},
],
};
const container = document.getElementById('container');
const width = container.scrollWidth;
const height = container.scrollHeight || 500;
const graph = new ExtGraph({
const graph = new Graph({
container: 'container',
width,
height,
modes: {
default: ['drag-canvas', 'drag-node', 'zoom-canvas', 'click-select'],
},
data,
layout: {
type: 'radial',
unitRadius: 70,
unitRadius: 100,
linkDistance: 100,
preventOverlap: true,
strictRadial: false,
},
edge: {
keyShape: {
endArrow: true,
node: {
style: {
labelText: (d) => d.id,
labelPlacement: 'center',
size: 20,
fill: '#EFF4FF',
lineWidth: 1,
stroke: '#5F95FF',
},
},
data,
edge: {
style: {
endArrow: {
path: 'M 0,0 L 8,4 L 8,-4 Z',
fill: '#e2e2e2',
},
},
},
behaviors: ['drag-canvas', 'drag-node'],
});
window.graph = graph;
graph.render();

View File

@ -1,539 +1,466 @@
import { Graph, Extensions, extend } from '@antv/g6';
const ExtGraph = extend(Graph, {
layouts: {
radial: Extensions.RadialLayout,
},
});
import { Graph } from '@antv/g6';
const data = {
nodes: [
{
id: '0',
data: {
label: '0',
},
sortAttr: 0,
sortAttr2: 'a',
},
{
id: '1',
data: {
label: '1',
},
sortAttr: 0,
sortAttr2: 'a',
},
{
id: '2',
data: {
label: '2',
},
sortAttr: 0,
sortAttr2: 'a',
},
{
id: '3',
data: {
label: '3',
},
sortAttr: 0,
sortAttr2: 'a',
},
{
id: '4',
data: {
label: '4',
},
sortAttr: 2,
sortAttr2: 'c',
},
{
id: '5',
data: {
label: '5',
},
sortAttr: 0,
sortAttr2: 'a',
},
{
id: '6',
data: {
label: '6',
},
sortAttr: 1,
sortAttr2: 'b',
},
{
id: '7',
data: {
label: '7',
},
sortAttr: 1,
sortAttr2: 'b',
},
{
id: '8',
data: {
label: '8',
},
sortAttr: 2,
sortAttr2: 'c',
},
{
id: '9',
data: {
label: '9',
},
sortAttr: 3,
sortAttr2: 'd',
},
{
id: '10',
data: {
label: '10',
},
sortAttr: 3,
sortAttr2: 'd',
},
{
id: '11',
data: {
label: '11',
},
sortAttr: 1,
sortAttr2: 'b',
},
{
id: '12',
data: {
label: '12',
},
sortAttr: 2,
sortAttr2: 'c',
},
{
id: '13',
data: {
label: '13',
},
sortAttr: 1,
sortAttr2: 'b',
},
{
id: '14',
data: {
label: '14',
},
sortAttr: 3,
sortAttr2: 'd',
},
{
id: '15',
data: {
label: '15',
},
sortAttr: 3,
sortAttr2: 'd',
},
{
id: '16',
data: {
label: '16',
},
sortAttr: 1,
sortAttr2: 'b',
},
{
id: '17',
data: {
label: '17',
},
sortAttr: 2,
sortAttr2: 'c',
},
{
id: '18',
data: {
label: '18',
},
sortAttr: 2,
sortAttr2: 'c',
},
{
id: '19',
data: {
label: '19',
},
sortAttr: 1,
sortAttr2: 'b',
},
{
id: '20',
data: {
label: '20',
},
sortAttr: 1,
sortAttr2: 'b',
},
{
id: '21',
data: {
label: '21',
},
sortAttr: 3,
sortAttr2: 'd',
},
{
id: '22',
data: {
label: '22',
},
sortAttr: 3,
sortAttr2: 'd',
},
{
id: '23',
data: {
label: '23',
},
sortAttr: 3,
sortAttr2: 'd',
},
{
id: '24',
data: {
label: '24',
},
sortAttr: 0,
sortAttr2: 'a',
},
{
id: '25',
data: {
label: '25',
},
sortAttr: 0,
sortAttr2: 'a',
},
{
id: '26',
data: {
label: '26',
},
sortAttr: 1,
sortAttr2: 'b',
},
{
id: '27',
data: {
label: '27',
},
sortAttr: 1,
sortAttr2: 'b',
},
{
id: '28',
data: {
label: '28',
},
sortAttr: 3,
sortAttr2: 'd',
},
{
id: '29',
data: {
label: '29',
},
sortAttr: 2,
sortAttr2: 'c',
},
{
id: '30',
data: {
label: '30',
},
sortAttr: 2,
sortAttr2: 'c',
},
{
id: '31',
data: {
label: '31',
},
sortAttr: 1,
sortAttr2: 'b',
},
{
id: '32',
data: {
label: '32',
},
sortAttr: 1,
sortAttr2: 'b',
},
{
id: '33',
data: {
label: '33',
},
sortAttr: 0,
sortAttr2: 'a',
},
],
edges: [
{
id: 'edge-841',
source: '0',
target: '1',
},
{
id: 'edge-655',
source: '0',
target: '2',
},
{
id: 'edge-404',
source: '0',
target: '3',
},
{
id: 'edge-601',
source: '0',
target: '4',
},
{
id: 'edge-554',
source: '0',
target: '5',
},
{
id: 'edge-50',
source: '0',
target: '7',
},
{
id: 'edge-369',
source: '0',
target: '8',
},
{
id: 'edge-239',
source: '0',
target: '9',
},
{
id: 'edge-475',
source: '0',
target: '10',
},
{
id: 'edge-342',
source: '0',
target: '11',
},
{
id: 'edge-63',
source: '0',
target: '13',
},
{
id: 'edge-26',
source: '0',
target: '14',
},
{
id: 'edge-33',
source: '0',
target: '15',
},
{
id: 'edge-867',
source: '0',
target: '16',
},
{
id: 'edge-620',
source: '2',
target: '3',
},
{
id: 'edge-843',
source: '4',
target: '5',
},
{
id: 'edge-832',
source: '4',
target: '6',
},
{
id: 'edge-157',
source: '5',
target: '6',
},
{
id: 'edge-48',
source: '7',
target: '13',
},
{
id: 'edge-114',
source: '8',
target: '14',
},
{
id: 'edge-912',
source: '9',
target: '10',
},
{
id: 'edge-494',
source: '10',
target: '22',
},
{
id: 'edge-960',
source: '10',
target: '14',
},
{
id: 'edge-384',
source: '10',
target: '12',
},
{
id: 'edge-94',
source: '10',
target: '24',
},
{
id: 'edge-361',
source: '10',
target: '21',
},
{
id: 'edge-299',
source: '10',
target: '20',
},
{
id: 'edge-645',
source: '11',
target: '24',
},
{
id: 'edge-487',
source: '11',
target: '22',
},
{
id: 'edge-622',
source: '11',
target: '14',
},
{
id: 'edge-21',
source: '12',
target: '13',
},
{
id: 'edge-286',
source: '16',
target: '17',
},
{
id: 'edge-643',
source: '16',
target: '18',
},
{
id: 'edge-306',
source: '16',
target: '21',
},
{
id: 'edge-45',
source: '16',
target: '22',
},
{
id: 'edge-912',
source: '17',
target: '18',
},
{
id: 'edge-820',
source: '17',
target: '20',
},
{
id: 'edge-399',
source: '18',
target: '19',
},
{
id: 'edge-186',
source: '19',
target: '20',
},
{
id: 'edge-220',
source: '19',
target: '33',
},
{
id: 'edge-577',
source: '19',
target: '22',
},
{
id: 'edge-191',
source: '19',
target: '23',
},
{
id: 'edge-390',
source: '20',
target: '21',
},
{
id: 'edge-304',
source: '21',
target: '22',
},
{
id: 'edge-888',
source: '22',
target: '24',
},
{
id: 'edge-795',
source: '22',
target: '25',
},
{
id: 'edge-716',
source: '22',
target: '26',
},
{
id: 'edge-100',
source: '22',
target: '23',
},
{
id: 'edge-933',
source: '22',
target: '28',
},
{
id: 'edge-193',
source: '22',
target: '30',
},
{
id: 'edge-748',
source: '22',
target: '31',
},
{
id: 'edge-176',
source: '22',
target: '32',
},
{
id: 'edge-525',
source: '22',
target: '33',
},
{
id: 'edge-795',
source: '23',
target: '28',
},
{
id: 'edge-311',
source: '23',
target: '27',
},
{
id: 'edge-499',
source: '23',
target: '29',
},
{
id: 'edge-418',
source: '23',
target: '30',
},
{
id: 'edge-409',
source: '23',
target: '31',
},
{
id: 'edge-426',
source: '23',
target: '33',
},
{
id: 'edge-876',
source: '32',
target: '33',
},
],
};
const container = document.getElementById('container');
const width = container.scrollWidth;
const height = container.scrollHeight || 500;
const graph = new ExtGraph({
const colors = ['steelblue', 'green', 'pink', 'grey'];
const colorsObj = { a: 'steelblue', b: 'green', c: 'pink', d: 'grey' };
const { nodes, edges } = data;
const graph = new Graph({
container: 'container',
width,
height,
modes: {
default: ['drag-canvas', 'drag-node', 'zoom-canvas', 'click-select'],
data: {
nodes: nodes.map((item) => ({
...item,
lineWidth: 4,
fill: '#fff',
stroke: colors[item.sortAttr2] || colorsObj[item.sortAttr2],
})),
edges,
},
layout: {
type: 'radial',
unitRadius: 150,
linkDistance: 200,
unitRadius: 70,
maxIteration: 1000,
linkDistance: 10,
preventOverlap: true,
nodeSize: 30,
sortBy: 'sortAttr2',
sortStrength: 50,
},
autoFit: 'center',
data,
node: {
style: {
labelText: (d) => d.id,
labelPlacement: 'center',
size: 20,
fill: '#EFF4FF',
lineWidth: 1,
stroke: '#5F95FF',
},
},
edge: {
style: {
endArrow: {
path: 'M 0,0 L 8,4 L 8,-4 Z',
fill: '#e2e2e2',
},
},
},
behaviors: ['drag-canvas', 'drag-node'],
});
window.graph = graph;
graph.render();

View File

@ -1,590 +0,0 @@
import { Graph, Extensions, extend } from '@antv/g6';
const ExtGraph = extend(Graph, {
layouts: {
radial: Extensions.RadialLayout,
},
});
const data = {
nodes: [
{
id: '0',
data: {
sortAttr: 0,
sortAttr2: 'a',
},
},
{
id: '1',
data: {
sortAttr: 0,
sortAttr2: 'a',
},
},
{
id: '2',
data: {
sortAttr: 0,
sortAttr2: 'a',
},
},
{
id: '3',
data: {
sortAttr: 0,
sortAttr2: 'a',
},
},
{
id: '4',
data: {
sortAttr: 2,
sortAttr2: 'c',
},
},
{
id: '5',
data: {
sortAttr: 0,
sortAttr2: 'a',
},
},
{
id: '6',
data: {
sortAttr: 1,
sortAttr2: 'b',
},
},
{
id: '7',
data: {
sortAttr: 1,
sortAttr2: 'b',
},
},
{
id: '8',
data: {
sortAttr: 2,
sortAttr2: 'c',
},
},
{
id: '9',
data: {
sortAttr: 3,
sortAttr2: 'd',
},
},
{
id: '10',
data: {
sortAttr: 3,
sortAttr2: 'd',
},
},
{
id: '11',
data: {
sortAttr: 1,
sortAttr2: 'b',
},
},
{
id: '12',
data: {
sortAttr: 2,
sortAttr2: 'c',
},
},
{
id: '13',
data: {
sortAttr: 1,
sortAttr2: 'b',
},
},
{
id: '14',
data: {
sortAttr: 3,
sortAttr2: 'd',
},
},
{
id: '15',
data: {
sortAttr: 3,
sortAttr2: 'd',
},
},
{
id: '16',
data: {
sortAttr: 1,
sortAttr2: 'b',
},
},
{
id: '17',
data: {
sortAttr: 2,
sortAttr2: 'c',
},
},
{
id: '18',
data: {
sortAttr: 2,
sortAttr2: 'c',
},
},
{
id: '19',
data: {
sortAttr: 1,
sortAttr2: 'b',
},
},
{
id: '20',
data: {
sortAttr: 1,
sortAttr2: 'b',
},
},
{
id: '21',
data: {
sortAttr: 3,
sortAttr2: 'd',
},
},
{
id: '22',
data: {
sortAttr: 3,
sortAttr2: 'd',
},
},
{
id: '23',
data: {
sortAttr: 3,
sortAttr2: 'd',
},
},
{
id: '24',
data: {
sortAttr: 0,
sortAttr2: 'a',
},
},
{
id: '25',
data: {
sortAttr: 0,
sortAttr2: 'a',
},
},
{
id: '26',
data: {
sortAttr: 1,
sortAttr2: 'b',
},
},
{
id: '27',
data: {
sortAttr: 1,
sortAttr2: 'b',
},
},
{
id: '28',
data: {
sortAttr: 3,
sortAttr2: 'd',
},
},
{
id: '29',
data: {
sortAttr: 2,
sortAttr2: 'c',
},
},
{
id: '30',
data: {
sortAttr: 2,
sortAttr2: 'c',
},
},
{
id: '31',
data: {
sortAttr: 1,
sortAttr2: 'b',
},
},
{
id: '32',
data: {
sortAttr: 1,
sortAttr2: 'b',
},
},
{
id: '33',
data: {
sortAttr: 0,
sortAttr2: 'a',
},
},
],
edges: [
{
id: 'edge-985',
source: '0',
target: '1',
},
{
id: 'edge-136',
source: '0',
target: '2',
},
{
id: 'edge-745',
source: '0',
target: '3',
},
{
id: 'edge-270',
source: '0',
target: '4',
},
{
id: 'edge-346',
source: '0',
target: '5',
},
{
id: 'edge-895',
source: '0',
target: '7',
},
{
id: 'edge-839',
source: '0',
target: '8',
},
{
id: 'edge-114',
source: '0',
target: '9',
},
{
id: 'edge-717',
source: '0',
target: '10',
},
{
id: 'edge-579',
source: '0',
target: '11',
},
{
id: 'edge-483',
source: '0',
target: '13',
},
{
id: 'edge-460',
source: '0',
target: '14',
},
{
id: 'edge-42',
source: '0',
target: '15',
},
{
id: 'edge-34',
source: '0',
target: '16',
},
{
id: 'edge-735',
source: '2',
target: '3',
},
{
id: 'edge-669',
source: '4',
target: '5',
},
{
id: 'edge-545',
source: '4',
target: '6',
},
{
id: 'edge-629',
source: '5',
target: '6',
},
{
id: 'edge-68',
source: '7',
target: '13',
},
{
id: 'edge-233',
source: '8',
target: '14',
},
{
id: 'edge-77',
source: '9',
target: '10',
},
{
id: 'edge-193',
source: '10',
target: '22',
},
{
id: 'edge-902',
source: '10',
target: '14',
},
{
id: 'edge-306',
source: '10',
target: '12',
},
{
id: 'edge-903',
source: '10',
target: '24',
},
{
id: 'edge-280',
source: '10',
target: '21',
},
{
id: 'edge-529',
source: '10',
target: '20',
},
{
id: 'edge-972',
source: '11',
target: '24',
},
{
id: 'edge-489',
source: '11',
target: '22',
},
{
id: 'edge-428',
source: '11',
target: '14',
},
{
id: 'edge-668',
source: '12',
target: '13',
},
{
id: 'edge-862',
source: '16',
target: '17',
},
{
id: 'edge-579',
source: '16',
target: '18',
},
{
id: 'edge-966',
source: '16',
target: '21',
},
{
id: 'edge-719',
source: '16',
target: '22',
},
{
id: 'edge-309',
source: '17',
target: '18',
},
{
id: 'edge-599',
source: '17',
target: '20',
},
{
id: 'edge-673',
source: '18',
target: '19',
},
{
id: 'edge-572',
source: '19',
target: '20',
},
{
id: 'edge-139',
source: '19',
target: '33',
},
{
id: 'edge-291',
source: '19',
target: '22',
},
{
id: 'edge-532',
source: '19',
target: '23',
},
{
id: 'edge-750',
source: '20',
target: '21',
},
{
id: 'edge-537',
source: '21',
target: '22',
},
{
id: 'edge-274',
source: '22',
target: '24',
},
{
id: 'edge-898',
source: '22',
target: '25',
},
{
id: 'edge-64',
source: '22',
target: '26',
},
{
id: 'edge-904',
source: '22',
target: '23',
},
{
id: 'edge-69',
source: '22',
target: '28',
},
{
id: 'edge-751',
source: '22',
target: '30',
},
{
id: 'edge-330',
source: '22',
target: '31',
},
{
id: 'edge-136',
source: '22',
target: '32',
},
{
id: 'edge-595',
source: '22',
target: '33',
},
{
id: 'edge-308',
source: '23',
target: '28',
},
{
id: 'edge-372',
source: '23',
target: '27',
},
{
id: 'edge-214',
source: '23',
target: '29',
},
{
id: 'edge-74',
source: '23',
target: '30',
},
{
id: 'edge-512',
source: '23',
target: '31',
},
{
id: 'edge-503',
source: '23',
target: '33',
},
{
id: 'edge-553',
source: '32',
target: '33',
},
],
};
const container = document.getElementById('container');
const width = container.scrollWidth;
const height = container.scrollHeight || 500;
const graph = new ExtGraph({
container: 'container',
width,
height,
modes: {
default: ['zoom-canvas', 'drag-canvas', 'drag-node', 'click-select'],
},
layout: {
type: 'radial',
unitRadius: 120,
maxIteration: 1000,
linkDistance: 50,
preventOverlap: true,
nodeSize: 30,
sortBy: 'sortAttr2',
sortStrength: 50,
},
theme: {
type: 'spec',
specification: {
node: {
dataTypeField: 'sortAttr2',
},
},
},
edge: {
keyShape: {
endArrow: true,
},
},
data,
});
window.graph = graph;

View File

@ -0,0 +1,26 @@
// global object
let GLOBALSTATE = {
staticCode: [],
};
const RESETGLOBAL = () => {
GLOBALSTATE = { staticCode: [] };
};
const SETGLOBAL = ([start, end]) => {
GLOBALSTATE['staticCode'].push([start, end]);
};
const INGLOBALRANGE = ([start, end]) => {
const { staticCode } = GLOBALSTATE;
let flag = false;
for (let i = 0; i < staticCode.length; i++) {
const [s, e] = staticCode[i];
if ((start >= s && start <= e) || (end >= s && end <= e)) {
flag = true;
}
}
return flag;
};
module.exports = { RESETGLOBAL, INGLOBALRANGE, SETGLOBAL };

View File

@ -0,0 +1,3 @@
const { parser, transformSign } = require('./parser');
module.exports = { parser, transformSign };

View File

@ -0,0 +1,53 @@
const fs = require('fs');
const babel = require('@babel/core');
const chalk = require('chalk');
const { get } = require('lodash');
const { isNewExpression, getObjectValue, transformSign } = require('./utils');
const meta = {
config: {}, // 图表配置项
code: '', // 原始代码
};
/**
* @param {string} params
* @param {string} type
* @description 解析代码提取 config
*/
const parser = (params, type) => {
try {
meta.code = fs.readFileSync(params, 'utf-8');
const visitorExpressions = {
// new Chart
NewExpression(path) {
const { node } = path;
if (isNewExpression(node)) {
meta.config = getObjectValue(get(node, 'arguments.0'), meta.code);
}
},
};
const vistorPlugins = {
visitor: visitorExpressions,
};
babel.transform(fs.readFileSync(params, 'utf-8'), {
plugins: [vistorPlugins, '@babel/plugin-transform-typescript'],
});
console.log(chalk.green(`解析成功:${params}`));
return {
success: true,
config: meta.config,
};
} catch (err) {
console.log(chalk.red(`解析出错params: ${params}; type: ${type}`));
console.log(chalk.red(`出错信息:${err}`));
return {
success: false,
errMessage: err,
errPath: params,
};
}
};
module.exports = { parser, transformSign };

View File

@ -0,0 +1,128 @@
const { get } = require('lodash');
const { SETGLOBAL } = require('./global');
const SIGN = '-FN-';
const startRegex = new RegExp(`"${SIGN}`, 'g');
const endRegex = new RegExp(`${SIGN}"`, 'g');
/**
* new表达式
* @param {*} node
*/
const isNewExpression = (node) => {
return get(node, 'callee.name') === 'Graph';
};
/**
* Is function
* @param {string} nodeType
*/
const isFunction = (nodeType) => {
return /FunctionExpression|ArrowFunctionExpression/.test(nodeType);
};
/**
* Use single
* @param {string} str
*/
const useSign = (str) => {
return replaceEnter(`${SIGN}${str}${SIGN}`);
};
/**
* Replace enter
* @param {*} str
*/
const replaceEnter = (str) => {
return str.replace(/\n/g, ' ');
};
/**
* transform sign
* @param {string} str
* @description 解析 meta 去掉 SIGN
*/
const transformSign = (str) => {
return str.replace(startRegex, '').replace(endRegex, '');
};
/**
* Get loop object
* @param {*} node
* @param {string} code code
*/
const getObjectValue = (node, code) => {
const { properties } = node;
const obj = {};
properties.forEach((item) => {
const { key, value } = item;
if (!['container', 'width', 'height', 'data'].includes(key.name)) {
if (isFunction(value.type)) {
const { start, end } = value;
SETGLOBAL([start, end]);
obj[key.name] = useSign(code.slice(start, end));
} else if (value.type === 'ArrayExpression') {
const { start, end } = value;
SETGLOBAL([start, end]);
obj[key.name] = useSign(code.slice(start, end));
} else if (value.type === 'ObjectExpression') {
// recursive
obj[key.name] = getObjectValue(value, code);
} else {
obj[key.name] = getValue(value);
}
}
});
return obj;
};
/**
* Get node value
* @param {*} arg
* @param {string} code
*/
const getValue = (arg, code = '') => {
const { start, end } = arg;
// .encode('y', 'frequency')
if (arg.type === 'StringLiteral') {
return arg.value;
}
// .encode('y', EPSILON)
if (arg.type === 'Identifier') {
return useSign(arg.name);
}
// .scale('y', { nice: true)
if (arg.type === 'ObjectExpression') {
return getObjectValue(arg, code);
}
// .encode('y', (d) => (d.sex === 1 ? -d.people : d.people))
if (isFunction(arg.type)) {
SETGLOBAL([start, end]);
return useSign(code.slice(start, end));
}
/**
* .data({
* transform: [
* {
* type: 'filter',
* callback: (d) => d.year === 2000,
* },
* ],
* })
*/
if (arg.type === 'ArrayExpression') {
SETGLOBAL([start, end]);
return useSign(code.slice(start, end));
}
return arg.value;
};
module.exports = {
isNewExpression,
isFunction,
useSign,
replaceEnter,
getObjectValue,
transformSign,
};

View File

@ -0,0 +1,110 @@
/**
* 为指定路径下的示例添加测试用例
* @param {string} path demo 路径
* @param {string} prifix 前缀
* @param {string} data 数据文件的
* @example
* - node scripts/demo-to-test/index net/radialLayout layout radial.json
* - explain: site/exmples/net/radialLayout 路径下的 demo 示例添加测试文件layout 为文件名Fn前缀radial.json 为数据文件
*/
const fs = require('fs');
const path = require('path');
const prettier = require('prettier');
const { uniq, camelCase, kebabCase } = require('lodash');
const { parser, transformSign } = require('./core');
const specTemplate = require('./template/spec');
const testTemplate = require('./template/test');
const itTemplate = require('./template/it');
const args = process.argv.slice(2);
const demoPath = args[0];
const name = kebabCase(demoPath.split('/').pop());
const prefix = args[1];
const dataFile = args[2];
const prePath = `../../packages/`;
const demoDir = path.resolve(__dirname, prePath, `site/examples/${demoPath}/demo`);
const testDir = path.resolve(__dirname, prePath, `g6/__tests__/demo/case`);
const unitDir = path.resolve(__dirname, prePath, `g6/__tests__/unit/${prefix}s`);
const exportDir = path.resolve(__dirname, prePath, `g6/__tests__/demo/case/index.ts`);
const unitMeta = [];
/**
* 移除 object string 左右 {}直接插入到已有 object
* @param text
*/
const removeFirstAndLastTwoChars = (text) => {
if (text.length < 4) {
return '';
}
return text.substring(2, text.length - 2);
};
const formatCode = async (code) => {
const formattedContent = await prettier.format(code, {
semi: true,
singleQuote: true,
printWidth: 120,
parser: 'typescript',
});
return formattedContent;
};
const initUnit = async () => {
const unitFiles = fs.readdirSync(unitDir);
let content = '';
let imported = '';
unitMeta.forEach(async (kebabName) => {
const camelName = camelCase(kebabName);
const sampleKebabName = kebabName.split('-').slice(2).join('-');
const config = { camelName, sampleKebabName, sampleKebabNameWithSpace: sampleKebabName.replace(/-/g, ' ') };
let exist = !!imported;
content += exist ? '\n\n' + itTemplate(config) : itTemplate(config);
imported += exist ? ',\n' + camelName : camelName;
fs.appendFileSync(exportDir, `export * from './${kebabName}';\n`, 'utf-8');
});
const filename = `./${name}.spec.ts`;
if (!unitFiles.includes(filename)) {
const formattedContent = await formatCode(
specTemplate({
content,
imported,
describe: `${uniq(name.split('-')).join(' ')}`,
}),
);
fs.writeFileSync(path.resolve(unitDir, filename), formattedContent, 'utf-8');
}
};
const initTest = async (dir) => {
const files = await fs.readdirSync(dir);
const testFiles = fs.readdirSync(testDir);
await files.forEach(async (file, index) => {
const filePath = path.resolve(dir, file);
const stats = fs.statSync(filePath);
const kebabName = uniq(`${prefix}-${name}-${kebabCase(file.replace('.ts', ''))}`.split('-')).join('-');
const camelName = camelCase(kebabName);
if (stats.isFile() && file.endsWith('.ts')) {
unitMeta.push(kebabName);
const { config, success } = parser(filePath);
if (success) {
const formattedContent = await formatCode(
testTemplate({
config: removeFirstAndLastTwoChars(transformSign(JSON.stringify(config, null, 2))),
filename: camelName,
dataFile,
}),
);
if (!testFiles.includes(`${kebabName}.ts`)) {
fs.writeFileSync(path.resolve(testDir, `./${kebabName}.ts`), formattedContent, 'utf-8');
}
}
}
if (index === files.length - 1) {
initUnit();
}
});
};
initTest(demoDir);

View File

@ -0,0 +1,9 @@
const itTemplate = ({ camelName, sampleKebabName, sampleKebabNameWithSpace }) => {
return `it('${sampleKebabNameWithSpace}', async () => {
const graph = await createDemoGraph(${camelName});
await expect(graph).toMatchSnapshot(__filename, '${sampleKebabName}');
graph.destroy();
});`;
};
module.exports = itTemplate;

View File

@ -0,0 +1,12 @@
const specTemplate = ({ imported, content, describe }) => {
return `import {
${imported}
} from '@@/demo/case';
import { createDemoGraph } from '@@/utils';
describe('${describe}', () => {
${content}
})`;
};
module.exports = specTemplate;

View File

@ -0,0 +1,20 @@
const testTemplate = ({ config, filename, dataFile }) => {
return `import { Graph } from '@/src';
import data from '@@/dataset/${dataFile}';
import type { STDTestCase } from '../types';
export const ${filename}: STDTestCase = async (context) => {
const graph = new Graph({
...context,
data,
${config}
});
await graph.render();
return graph;
};
`;
};
module.exports = testTemplate;