Commit 6a058b83 by zhaochengxiang

优化组织图 树形图

parent 39444b1a
......@@ -5,10 +5,29 @@ import { ContextPath } from '../../../../util';
let graph = null;
const rectWidth = 120;
const rectHeight = 40;
const globalFontSize = 20;
const COLLAPSE_ICON = function COLLAPSE_ICON(x, y, r) {
return [
['M', x - r, y - r],
['a', r, r, 0, 1, 0, r * 2, 0],
['a', r, r, 0, 1, 0, -r * 2, 0],
['M', x + 2 - r, y - r],
['L', x + r - 2, y - r],
];
};
const EXPAND_ICON = function EXPAND_ICON(x, y, r) {
return [
['M', x - r, y - r],
['a', r, r, 0, 1, 0, r * 2, 0],
['a', r, r, 0, 1, 0, -r * 2, 0],
['M', x + 2 - r, y - r],
['L', x + r - 2, y - r],
['M', x, y - 2 * r + 2],
['L', x, y - 2],
];
};
class Org extends React.Component {
componentDidMount() {
......@@ -23,35 +42,62 @@ class Org extends React.Component {
G6.registerNode(
'org-node',
{
draw(cfg, group) {
const styles = this.getShapeStyle(cfg);
const { labelCfg = {} } = cfg;
const w = styles.width;
const h = styles.height;
group.addShape('rect', {
draw(cfg, group) {
const rect = group.addShape('rect', {
attrs: {
fill: '#fff',
stroke: '#666',
radius: 5,
cursor: 'pointer',
},
});
const content = (cfg.label||'').replace(/(.{19})/g, '$1\n');
const text = group.addShape('text', {
attrs: {
...styles,
x: 0,
y: 0,
width: w,
height: h
},
fill: '#000',
fontSize: globalFontSize,
textAlign: 'left',
textBaseline: 'middle',
text: content,
}
});
if (cfg.label) {
group.addShape('text', {
const bbox = text.getBBox();
if (!cfg.children) {
group.addShape('marker', {
attrs: {
x: bbox.maxX + 12,
y: bbox.height/2 -3,
r: 6,
symbol: EXPAND_ICON,
stroke: '#73d13d',
lineWidth: 2,
}
});
} else if ((cfg.children||[]).length>0) {
group.addShape('marker', {
attrs: {
...labelCfg.style,
x: w/2,
y: h/2,
textAlign: 'center',
textBaseline: 'middle',
text: cfg.label,
x: bbox.maxX + 12,
y: bbox.height/2 -3,
r: 6,
symbol: cfg.collapsed ? EXPAND_ICON : COLLAPSE_ICON,
stroke: cfg.collapsed ? '#73d13d' : '#ff4d4f',
lineWidth: 2,
}
});
}
rect.attr({
x: bbox.minX - 10,
y: bbox.minY - 10,
width: bbox.width + (!cfg.children||((cfg.children||[]).length>0) ? 38 : 20),
height: bbox.height + 20,
});
return group;
},
......@@ -118,28 +164,6 @@ class Org extends React.Component {
},
});
const defaultNodeStyle = {
fill: '#91d5ff',
stroke: '#40a9ff',
radius: 5,
};
const defaultLabelCfg = {
style: {
fill: '#000',
fontSize: globalFontSize,
},
};
const defaultEdgeStyle = {
stroke: '#91d5ff',
endArrow: {
path: 'M 0,0 L 12, 6 L 9,0 L 12, -6 Z',
fill: '#91d5ff',
d: -20,
},
};
graph = new G6.TreeGraph({
container: `container${type||''}`,
width,
......@@ -167,13 +191,9 @@ class Org extends React.Component {
},
defaultNode: {
type: 'org-node',
size: [rectWidth, rectHeight],
style: defaultNodeStyle,
labelCfg: defaultLabelCfg,
},
defaultEdge: {
type: 'flow-line',
style: defaultEdgeStyle,
},
layout: {
type: 'compactBox',
......@@ -181,12 +201,6 @@ class Org extends React.Component {
getId: function getId(d) {
return d.id;
},
getHeight: function getHeight() {
return 16;
},
getWidth: function getWidth() {
return 16;
},
getVGap: function getVGap() {
return 40;
},
......@@ -229,31 +243,10 @@ class Org extends React.Component {
const { data } = this.props;
if(graph && data){
const fittingString = (str, maxWidth, fontSize) => {
const ellipsis = '...';
const ellipsisLength = G6.Util.getTextSize(ellipsis, fontSize)[0];
let currentWidth = 0;
let res = str;
const pattern = new RegExp('[\u4E00-\u9FA5]+'); // distinguish the Chinese charactors and letters
str.split('').forEach((letter, i) => {
if (currentWidth > maxWidth - ellipsisLength) return;
if (pattern.test(letter)) {
// Chinese charactors
currentWidth += fontSize;
} else {
// get the width of single letter according to the fontSize
currentWidth += G6.Util.getLetterWidth(letter, fontSize);
}
if (currentWidth > maxWidth - ellipsisLength) {
res = `${str.substr(0, i)}${ellipsis}`;
}
});
return res;
};
graph.node(function (node) {
return {
label: fittingString(node.text||'', rectWidth-4, globalFontSize),
label: (node.text||''),
};
});
......
......@@ -4,9 +4,29 @@ import G6 from '@antv/g6';
import { ContextPath } from '../../../../util';
let graph = null;
const maxTextWidth = 116;
const globalFontSize = 20;
const COLLAPSE_ICON = function COLLAPSE_ICON(x, y, r) {
return [
['M', x - r, y - r],
['a', r, r, 0, 1, 0, r * 2, 0],
['a', r, r, 0, 1, 0, -r * 2, 0],
['M', x + 2 - r, y - r],
['L', x + r - 2, y - r],
];
};
const EXPAND_ICON = function EXPAND_ICON(x, y, r) {
return [
['M', x - r, y - r],
['a', r, r, 0, 1, 0, r * 2, 0],
['a', r, r, 0, 1, 0, -r * 2, 0],
['M', x + 2 - r, y - r],
['L', x + r - 2, y - r],
['M', x, y - 2 * r + 2],
['L', x, y - 2],
];
};
class Tree extends React.Component {
componentDidMount() {
......@@ -18,6 +38,73 @@ class Tree extends React.Component {
const width = container.scrollWidth;
const height = container.scrollHeight || 500;
G6.registerNode(
'tree-node',
{
draw(cfg, group) {
const rect = group.addShape('rect', {
attrs: {
fill: '#fff',
stroke: '#666',
radius: 5,
cursor: 'pointer',
},
});
const content = (cfg.label||'').replace(/(.{19})/g, '$1\n');
const text = group.addShape('text', {
attrs: {
x: 0,
y: 0,
fill: '#000',
fontSize: globalFontSize,
textAlign: 'left',
textBaseline: 'middle',
text: content,
}
});
const bbox = text.getBBox();
if (!cfg.children) {
group.addShape('marker', {
attrs: {
x: bbox.maxX + 12,
y: bbox.height/2 -3,
r: 6,
symbol: EXPAND_ICON,
stroke: '#73d13d',
lineWidth: 2,
}
});
} else if ((cfg.children||[]).length>0) {
group.addShape('marker', {
attrs: {
x: bbox.maxX + 12,
y: bbox.height/2 -3,
r: 6,
symbol: cfg.collapsed ? EXPAND_ICON : COLLAPSE_ICON,
stroke: cfg.collapsed ? '#73d13d' : '#ff4d4f',
lineWidth: 2,
}
});
}
rect.attr({
x: bbox.minX - 10,
y: bbox.minY - 10,
width: bbox.width + (!cfg.children||((cfg.children||[]).length>0) ? 38 : 20),
height: bbox.height + 20,
});
return group;
},
update: undefined,
},
'single-node'
);
const tooltip = new G6.Tooltip({
offsetX: 10,
offsetY: 10,
......@@ -49,6 +136,9 @@ class Tree extends React.Component {
type: 'collapse-expand',
onChange: function onChange(item, collapsed) {
const data = item.get('model');
graph.updateItem(item, {
collapsed,
});
data.collapsed = collapsed;
return true;
},
......@@ -58,25 +148,27 @@ class Tree extends React.Component {
],
},
defaultNode: {
type: 'tree-node',
anchorPoints: [
[0, 0.5],
[1, 0.5],
],
labelCfg: {
style: {
fill: '#000',
fontSize: globalFontSize,
},
}
},
defaultEdge: {
type: 'cubic-horizontal',
},
layout: {
type: 'dendrogram',
type: 'compactBox',
direction: 'LR', // H / V / LR / RL / TB / BT
nodeSep: 30,
rankSep: 100,
getId: function getId(d) {
return d.id;
},
getVGap: function getVGap() {
return 20;
},
getHGap: function getHGap() {
return 80;
},
},
});
......@@ -113,35 +205,10 @@ class Tree extends React.Component {
const { data } = this.props;
if(graph && data){
const fittingString = (str, maxWidth, fontSize) => {
const ellipsis = '...';
const ellipsisLength = G6.Util.getTextSize(ellipsis, fontSize)[0];
let currentWidth = 0;
let res = str;
const pattern = new RegExp('[\u4E00-\u9FA5]+'); // distinguish the Chinese charactors and letters
str.split('').forEach((letter, i) => {
if (currentWidth > maxWidth - ellipsisLength) return;
if (pattern.test(letter)) {
// Chinese charactors
currentWidth += fontSize;
} else {
// get the width of single letter according to the fontSize
currentWidth += G6.Util.getLetterWidth(letter, fontSize);
}
if (currentWidth > maxWidth - ellipsisLength) {
res = `${str.substr(0, i)}${ellipsis}`;
}
});
return res;
};
graph.node(function (node) {
return {
label: fittingString(node.text||'', maxTextWidth, globalFontSize),
labelCfg: {
position: node.children && node.children.length > 0 ? 'left' : 'right',
offset: 5,
},
label: node.text||'',
};
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment