mirror of
https://gitee.com/antv/g6.git
synced 2024-11-29 18:28:19 +08:00
docs: treegraph scene case
This commit is contained in:
parent
46d0172d77
commit
a97a3b6433
@ -20,38 +20,6 @@
|
||||
},
|
||||
"screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*IytGRZ8WaSMAAAAAAAAAAAAADmJ7AQ/original"
|
||||
},
|
||||
{
|
||||
"filename": "indented-tree.js",
|
||||
"title": {
|
||||
"zh": "缩进树",
|
||||
"en": "Indented Tree"
|
||||
},
|
||||
"screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*r0-SS5dRxykAAAAAAAAAAAAADmJ7AQ/original"
|
||||
},
|
||||
{
|
||||
"filename": "mindmap.js",
|
||||
"title": {
|
||||
"zh": "思维导图",
|
||||
"en": "Mind Map"
|
||||
},
|
||||
"screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*P39BR7WoI5oAAAAAAAAAAAAADmJ7AQ/original"
|
||||
},
|
||||
{
|
||||
"filename": "radial-dendrogram.js",
|
||||
"title": {
|
||||
"zh": "径向生态树",
|
||||
"en": "Radial Dendrogram"
|
||||
},
|
||||
"screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*WRXHSrxqBYsAAAAAAAAAAAAADmJ7AQ/original"
|
||||
},
|
||||
{
|
||||
"filename": "radial-compact-tree.js",
|
||||
"title": {
|
||||
"zh": "径向紧凑树",
|
||||
"en": "Radial Compact Tree"
|
||||
},
|
||||
"screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*uKYKSYJ6iMYAAAAAAAAAAAAADmJ7AQ/original"
|
||||
},
|
||||
{
|
||||
"filename": "fund-flow.js",
|
||||
"title": {
|
||||
|
@ -2,28 +2,43 @@ import { Text } from '@antv/g';
|
||||
import { BaseTransform, ExtensionCategory, Graph, register, treeToGraphData } from '@antv/g6';
|
||||
|
||||
const data = {
|
||||
id: '克服拖延',
|
||||
id: 'Overcome procrastination',
|
||||
children: [
|
||||
{ id: '完美主义情结', children: [{ id: '正确评估事情难度' }, { id: '先完成,再完善' }, { id: 'Just do it' }] },
|
||||
{
|
||||
id: '提高专注度',
|
||||
children: [{ id: '番茄工作法' }, { id: '限时、限量,一次只做一件事' }, { id: '提高抗干扰能力,减少打断' }],
|
||||
},
|
||||
{
|
||||
id: '设定清晰的任务管理流程',
|
||||
id: 'Perfectionism',
|
||||
children: [
|
||||
{ id: '设立完成事项的优先级' },
|
||||
{ id: '拆解具体可执行的目标' },
|
||||
{ id: '收集-整理-排序-执行反馈-总结' },
|
||||
{ id: 'Correctly assess the difficulty of things' },
|
||||
{ id: 'Complete first, then improve' },
|
||||
{ id: 'Just do it' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: '建立积极反馈',
|
||||
children: [{ id: '做喜欢的事情' }, { id: '精神激励' }, { id: '物质激励' }],
|
||||
id: 'Improve concentration',
|
||||
children: [
|
||||
{ id: 'Pomodoro Technique' },
|
||||
{ id: 'Limited time, limited quantity, only do one thing at a time' },
|
||||
{ id: 'Improve anti-interference ability, reduce interruptions' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: '放松、享受',
|
||||
children: [{ id: '注重过程而非结果' }, { id: '靠需求驱动而非焦虑' }, { id: '接受、理解' }],
|
||||
id: 'Set a clear task management process',
|
||||
children: [
|
||||
{ id: 'Set priorities for completed tasks' },
|
||||
{ id: 'Break down specific executable goals' },
|
||||
{ id: 'Collect-sort-sort-execute feedback-summary' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'Establish positive feedback',
|
||||
children: [{ id: 'Do what you like' }, { id: 'Spiritual motivation' }, { id: 'Material motivation' }],
|
||||
},
|
||||
{
|
||||
id: 'Relax and enjoy',
|
||||
children: [
|
||||
{ id: 'Focus on process rather than results' },
|
||||
{ id: 'Driven by needs rather than anxiety' },
|
||||
{ id: 'Accept and understand' },
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
@ -104,7 +119,7 @@ const getNodeSize = (id, depth) => {
|
||||
? [measureText({ text: id, fontSize: 24, fontWeight: 'bold', fontFamily: FONT_FAMILY }) + 80, 58]
|
||||
: depth === 1
|
||||
? [measureText({ text: id, fontSize: 18, fontFamily: FONT_FAMILY }) + 50, 42]
|
||||
: [0, 30];
|
||||
: [2, 30];
|
||||
};
|
||||
|
||||
const graph = new Graph({
|
||||
@ -119,6 +134,7 @@ const graph = new Graph({
|
||||
size: getNodeSize(d.id, d.depth),
|
||||
labelText: d.id,
|
||||
labelPlacement: 'right',
|
||||
labelFontFamily: 'Gill Sans',
|
||||
};
|
||||
|
||||
if (d.depth === 0) {
|
||||
@ -135,7 +151,7 @@ const graph = new Graph({
|
||||
labelFontSize: 18,
|
||||
labelFill: '#fff',
|
||||
labelFillOpacity: 0.9,
|
||||
labelOffsetY: 3,
|
||||
labelOffsetY: 5,
|
||||
labelPlacement: 'center',
|
||||
fill: d.style?.color,
|
||||
});
|
||||
|
@ -4,13 +4,45 @@
|
||||
"en": "Category"
|
||||
},
|
||||
"demos": [
|
||||
{
|
||||
"filename": "indented-tree.js",
|
||||
"title": {
|
||||
"zh": "缩进树",
|
||||
"en": "Indented Tree"
|
||||
},
|
||||
"screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*r0-SS5dRxykAAAAAAAAAAAAADmJ7AQ/original"
|
||||
},
|
||||
{
|
||||
"filename": "mindmap.js",
|
||||
"title": {
|
||||
"zh": "思维导图",
|
||||
"en": "Mind Map"
|
||||
},
|
||||
"screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*xryoSY8EQWoAAAAAAAAAAAAADmJ7AQ/original"
|
||||
},
|
||||
{
|
||||
"filename": "anti-procrastination-fishbone.js",
|
||||
"title": {
|
||||
"zh": "克服拖延症鱼骨图",
|
||||
"en": "Anti-Procrastination Fishbone Diagram"
|
||||
},
|
||||
"screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*VusPQ50s3uEAAAAAAAAAAAAADmJ7AQ/original"
|
||||
"screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*SRNFSbINb0AAAAAAAAAAAAAADmJ7AQ/fmt.webp"
|
||||
},
|
||||
{
|
||||
"filename": "radial-dendrogram.js",
|
||||
"title": {
|
||||
"zh": "径向生态树",
|
||||
"en": "Radial Dendrogram"
|
||||
},
|
||||
"screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*tK5USKBOc2kAAAAAAAAAAAAADmJ7AQ/original"
|
||||
},
|
||||
{
|
||||
"filename": "radial-compact-tree.js",
|
||||
"title": {
|
||||
"zh": "径向紧凑树",
|
||||
"en": "Radial Compact Tree"
|
||||
},
|
||||
"screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*9iPNRpKfb3IAAAAAAAAAAAAADmJ7AQ/original"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -21,33 +21,21 @@ const style = document.createElement('style');
|
||||
style.innerHTML = `@import url('${iconfont.css}');`;
|
||||
document.head.appendChild(style);
|
||||
|
||||
const COLORS = [
|
||||
'#1783FF',
|
||||
'#00C9C9',
|
||||
'#F08F56',
|
||||
'#D580FF',
|
||||
'#7863FF',
|
||||
'#DB9D0D',
|
||||
'#60C42D',
|
||||
'#FF80CA',
|
||||
'#2491B3',
|
||||
'#17C76F',
|
||||
];
|
||||
|
||||
const RootNodeStyle = {
|
||||
fill: '#EFF0F0',
|
||||
labelFill: '#262626',
|
||||
labelFontSize: 16,
|
||||
labelFontSize: 24,
|
||||
labelFontWeight: 600,
|
||||
labelOffsetY: 8,
|
||||
labelPlacement: 'center',
|
||||
ports: [{ placement: 'right' }, { placement: 'left' }],
|
||||
radius: 4,
|
||||
radius: 8,
|
||||
};
|
||||
|
||||
const NodeStyle = {
|
||||
fill: 'transparent',
|
||||
labelPlacement: 'center',
|
||||
labelFontSize: 12,
|
||||
labelFontSize: 16,
|
||||
ports: [{ placement: 'right-bottom' }, { placement: 'left-bottom' }],
|
||||
};
|
||||
|
||||
@ -64,9 +52,15 @@ const measureText = (text) => {
|
||||
};
|
||||
|
||||
const getNodeWidth = (nodeId, isRoot) => {
|
||||
return isRoot
|
||||
? measureText({ text: nodeId, fontSize: RootNodeStyle.labelFontSize }) + 20
|
||||
: measureText({ text: nodeId, fontSize: NodeStyle.labelFontSize }) + 30;
|
||||
const padding = isRoot ? 40 : 30;
|
||||
const nodeStyle = isRoot ? RootNodeStyle : NodeStyle;
|
||||
return measureText({ text: nodeId, fontSize: nodeStyle.labelFontSize, fontFamily: 'Gill Sans' }) + padding;
|
||||
};
|
||||
|
||||
const getNodeSize = (nodeId, isRoot) => {
|
||||
const width = getNodeWidth(nodeId, isRoot);
|
||||
const height = isRoot ? 48 : 32;
|
||||
return [width, height];
|
||||
};
|
||||
|
||||
class MindmapNode extends BaseNode {
|
||||
@ -186,7 +180,7 @@ class MindmapNode extends BaseNode {
|
||||
}
|
||||
|
||||
getAddBarStyle(attributes) {
|
||||
const { collapsed, showIcon, direction, color = COLORS[0] } = attributes;
|
||||
const { collapsed, showIcon, direction, color = '#1783FF' } = attributes;
|
||||
if (collapsed || !showIcon) return false;
|
||||
const [width, height] = this.getSize(attributes);
|
||||
|
||||
@ -352,42 +346,51 @@ class CollapseExpandTree extends BaseBehavior {
|
||||
};
|
||||
}
|
||||
|
||||
class AssignElementColor extends BaseTransform {
|
||||
beforeDraw(data) {
|
||||
const { nodes = [], edges = [] } = this.context.graph.getData();
|
||||
class AssignColorByBranch extends BaseTransform {
|
||||
static defaultOptions = {
|
||||
colors: [
|
||||
'#1783FF',
|
||||
'#F08F56',
|
||||
'#D580FF',
|
||||
'#00C9C9',
|
||||
'#7863FF',
|
||||
'#DB9D0D',
|
||||
'#60C42D',
|
||||
'#FF80CA',
|
||||
'#2491B3',
|
||||
'#17C76F',
|
||||
],
|
||||
};
|
||||
|
||||
const nodeColorMap = new Map();
|
||||
constructor(context, options) {
|
||||
super(context, Object.assign({}, AssignColorByBranch.defaultOptions, options));
|
||||
}
|
||||
|
||||
beforeDraw(input) {
|
||||
const nodes = this.context.model.getNodeData();
|
||||
|
||||
if (nodes.length === 0) return input;
|
||||
|
||||
let colorIndex = 0;
|
||||
const dfs = (nodeId, color) => {
|
||||
const node = nodes.find((datum) => datum.id == nodeId);
|
||||
if (!node) return;
|
||||
|
||||
if (node.depth !== 0) {
|
||||
const nodeColor = color || COLORS[colorIndex++ % COLORS.length];
|
||||
node.style ||= {};
|
||||
node.style.color = nodeColor;
|
||||
nodeColorMap.set(nodeId, nodeColor);
|
||||
}
|
||||
|
||||
node.children?.forEach((childId) => dfs(childId, node.style.color));
|
||||
node.style ||= {};
|
||||
node.style.color = color || this.options.colors[colorIndex++ % this.options.colors.length];
|
||||
node.children?.forEach((childId) => dfs(childId, node.style?.color));
|
||||
};
|
||||
|
||||
nodes.filter((node) => node.depth === 0).forEach((rootNode) => dfs(rootNode.id));
|
||||
nodes.filter((node) => node.depth === 1).forEach((rootNode) => dfs(rootNode.id));
|
||||
|
||||
edges.forEach((edge) => {
|
||||
edge.style ||= {};
|
||||
edge.style.stroke = nodeColorMap.get(edge.target);
|
||||
});
|
||||
|
||||
return data;
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
register(ExtensionCategory.NODE, 'mindmap', MindmapNode);
|
||||
register(ExtensionCategory.EDGE, 'mindmap', MindmapEdge);
|
||||
register(ExtensionCategory.BEHAVIOR, 'collapse-expand-tree', CollapseExpandTree);
|
||||
register(ExtensionCategory.TRANSFORM, 'assign-element-color', AssignElementColor);
|
||||
register(ExtensionCategory.TRANSFORM, 'assign-color-by-branch', AssignColorByBranch);
|
||||
|
||||
const getNodeSide = (nodeData, parentData) => {
|
||||
if (!parentData) return 'center';
|
||||
@ -413,9 +416,9 @@ fetch('https://assets.antv.antgroup.com/g6/algorithm-category.json')
|
||||
return {
|
||||
direction,
|
||||
labelText: idOf(d),
|
||||
size: [getNodeWidth(idOf(d), isRoot), 30],
|
||||
// 通过设置节点标签背景来扩大节点的交互区域
|
||||
// Enlarge the interactive area of the node by setting label background
|
||||
size: getNodeSize(idOf(d), isRoot),
|
||||
labelFontFamily: 'Gill Sans',
|
||||
// 通过设置节点标签背景来扩大交互区域 | Expand the interaction area by setting the node label background
|
||||
labelBackground: true,
|
||||
labelBackgroundFill: 'transparent',
|
||||
labelPadding: direction === 'left' ? [2, 0, 10, 40] : [2, 40, 10, 0],
|
||||
@ -425,7 +428,12 @@ fetch('https://assets.antv.antgroup.com/g6/algorithm-category.json')
|
||||
},
|
||||
edge: {
|
||||
type: 'mindmap',
|
||||
style: { lineWidth: 2 },
|
||||
style: {
|
||||
lineWidth: 3,
|
||||
stroke: function (data) {
|
||||
return this.getNodeData(data.target).style.color || '#99ADD1';
|
||||
},
|
||||
},
|
||||
},
|
||||
layout: {
|
||||
type: 'mindmap',
|
||||
@ -437,7 +445,7 @@ fetch('https://assets.antv.antgroup.com/g6/algorithm-category.json')
|
||||
animation: false,
|
||||
},
|
||||
behaviors: ['drag-canvas', 'zoom-canvas', 'collapse-expand-tree'],
|
||||
transforms: ['assign-element-color'],
|
||||
transforms: ['assign-color-by-branch'],
|
||||
animation: false,
|
||||
});
|
||||
|
@ -6,34 +6,30 @@ fetch('https://assets.antv.antgroup.com/g6/flare.json')
|
||||
const graph = new Graph({
|
||||
container: 'container',
|
||||
autoFit: 'view',
|
||||
padding: 50,
|
||||
data: treeToGraphData(data),
|
||||
node: {
|
||||
style: {
|
||||
size: 20,
|
||||
size: 12,
|
||||
labelText: (d) => d.id,
|
||||
labelBackground: true,
|
||||
},
|
||||
state: {
|
||||
active: {
|
||||
fill: '#00C9C9',
|
||||
},
|
||||
labelFontSize: 14,
|
||||
labelFontFamily: 'Gill Sans',
|
||||
},
|
||||
},
|
||||
edge: {
|
||||
type: 'cubic-radial',
|
||||
state: {
|
||||
active: {
|
||||
lineWidth: 3,
|
||||
stroke: '#009999',
|
||||
},
|
||||
style: {
|
||||
lineWidth: 3,
|
||||
},
|
||||
},
|
||||
layout: [
|
||||
{
|
||||
type: 'dendrogram',
|
||||
type: 'compact-box',
|
||||
radial: true,
|
||||
nodeSep: 30,
|
||||
rankSep: 200,
|
||||
direction: 'RL',
|
||||
getVGap: () => 40,
|
||||
getHGap: () => 80,
|
||||
},
|
||||
],
|
||||
behaviors: [
|
||||
@ -49,6 +45,7 @@ fetch('https://assets.antv.antgroup.com/g6/flare.json')
|
||||
},
|
||||
],
|
||||
transforms: ['place-radial-labels'],
|
||||
animation: false,
|
||||
});
|
||||
|
||||
graph.render();
|
@ -6,47 +6,27 @@ fetch('https://assets.antv.antgroup.com/g6/flare.json')
|
||||
const graph = new Graph({
|
||||
container: 'container',
|
||||
autoFit: 'view',
|
||||
padding: 50,
|
||||
data: treeToGraphData(data),
|
||||
node: {
|
||||
style: {
|
||||
size: 20,
|
||||
size: 12,
|
||||
labelText: (d) => d.id,
|
||||
labelBackground: true,
|
||||
},
|
||||
state: {
|
||||
active: {
|
||||
fill: '#00C9C9',
|
||||
},
|
||||
labelFontSize: 14,
|
||||
labelFontFamily: 'Gill Sans',
|
||||
},
|
||||
},
|
||||
edge: {
|
||||
type: 'cubic-radial',
|
||||
state: {
|
||||
active: {
|
||||
lineWidth: 3,
|
||||
stroke: '#009999',
|
||||
},
|
||||
style: {
|
||||
lineWidth: 3,
|
||||
},
|
||||
},
|
||||
layout: [
|
||||
{
|
||||
type: 'compact-box',
|
||||
radial: true,
|
||||
direction: 'RL',
|
||||
getHeight: () => {
|
||||
return 20;
|
||||
},
|
||||
getWidth: () => {
|
||||
return 20;
|
||||
},
|
||||
getVGap: () => {
|
||||
return 20;
|
||||
},
|
||||
getHGap: () => {
|
||||
return 80;
|
||||
},
|
||||
},
|
||||
],
|
||||
layout: {
|
||||
type: 'dendrogram',
|
||||
radial: true,
|
||||
},
|
||||
behaviors: [
|
||||
'drag-canvas',
|
||||
'zoom-canvas',
|
||||
@ -60,6 +40,7 @@ fetch('https://assets.antv.antgroup.com/g6/flare.json')
|
||||
},
|
||||
],
|
||||
transforms: ['place-radial-labels'],
|
||||
animation: false,
|
||||
});
|
||||
|
||||
graph.render();
|
Loading…
Reference in New Issue
Block a user