docs: treegraph scene case

This commit is contained in:
yvonneyx 2024-11-11 13:58:22 +08:00
parent 46d0172d77
commit a97a3b6433
7 changed files with 140 additions and 138 deletions

View File

@ -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": {

View File

@ -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,
});

View File

@ -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"
}
]
}

View File

@ -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,
});

View File

@ -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();

View File

@ -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();