mirror of
https://gitee.com/antv/g6.git
synced 2024-12-05 05:09:07 +08:00
feat: add label rotate
This commit is contained in:
parent
0ca0dbc301
commit
0b0e749045
305
demos/test.html
305
demos/test.html
@ -46,208 +46,123 @@
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<script>
|
<script>
|
||||||
console.log(G6.version);
|
|
||||||
G6.registerNode('card', {
|
|
||||||
collapseButtonUrl:
|
|
||||||
'https://gw.alipayobjects.com/zos/rmsportal/GGzWwlTjflbJHmXhjMXg.svg',
|
|
||||||
expandButtonUrl:
|
|
||||||
'https://gw.alipayobjects.com/zos/rmsportal/DzWdTiwanggjaWKwcnWZ.svg',
|
|
||||||
draw(item) {
|
|
||||||
const group = item.getGraphicGroup();
|
|
||||||
const { main, value, percent, type, collapsed, children } = item.getModel();
|
|
||||||
const width = 170;
|
|
||||||
const height = 80;
|
|
||||||
const buttonWidth = 14;
|
|
||||||
const buttonHeight = 14;
|
|
||||||
let button = '';
|
|
||||||
if (children && children.length > 0) {
|
|
||||||
button =
|
|
||||||
'<img class="ce-button" src=' +
|
|
||||||
(collapsed ? this.expandButtonUrl : this.collapseButtonUrl) +
|
|
||||||
'>';
|
|
||||||
}
|
|
||||||
const html = G6.Util.createDOM(`
|
|
||||||
<div class="card-container">
|
|
||||||
<h1 class="main-text">${main}</h1>
|
|
||||||
<p>
|
|
||||||
<span class="value-text">${value}</span>
|
|
||||||
<span class="percent-text">${percent}</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
`);
|
|
||||||
const keyShape = group.addShape('dom', {
|
|
||||||
attrs: {
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
html,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
group.addShape('dom', {
|
|
||||||
attrs: {
|
|
||||||
x: width / 2 - buttonWidth / 2,
|
|
||||||
y: height - buttonHeight + 2,
|
|
||||||
width: buttonWidth,
|
|
||||||
height: buttonHeight,
|
|
||||||
html: button,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
return group;
|
|
||||||
},
|
|
||||||
anchor: [[0.5, 0], [0.5, 1]],
|
|
||||||
});
|
|
||||||
const data = {
|
const data = {
|
||||||
roots: [
|
"name": "Modeling Methods",
|
||||||
|
"children": [
|
||||||
{
|
{
|
||||||
main: '主指标一',
|
"name": "Classification",
|
||||||
value: 123111,
|
"children": [
|
||||||
percent: '100%',
|
{ "name": "Logistic regression" },
|
||||||
type: '1',
|
{ "name": "Linear discriminant analysis" },
|
||||||
children: [
|
{ "name": "Rules" },
|
||||||
{
|
{ "name": "Decision trees" },
|
||||||
main: '指标 1',
|
{ "name": "Naive Bayes" },
|
||||||
value: 12312,
|
{ "name": "K nearest neighbor" },
|
||||||
percent: '39%',
|
{ "name": "Probabilistic neural network" },
|
||||||
type: '2',
|
{ "name": "Support vector machine" }
|
||||||
children: [
|
]
|
||||||
{
|
|
||||||
main: '指标 1.1',
|
|
||||||
value: 111,
|
|
||||||
percent: '90%',
|
|
||||||
type: '3',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
main: '指标 1.11',
|
|
||||||
value: 111,
|
|
||||||
percent: '90%',
|
|
||||||
type: '113',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
main: '指标 1.12',
|
|
||||||
value: 111,
|
|
||||||
percent: '90%',
|
|
||||||
type: '14',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
main: '指标 1.2',
|
|
||||||
value: 111,
|
|
||||||
percent: '90%',
|
|
||||||
type: '4',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
main: '指标 1.21',
|
|
||||||
value: 111,
|
|
||||||
percent: '90%',
|
|
||||||
type: '5',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
main: '指标 1.22',
|
|
||||||
value: 111,
|
|
||||||
percent: '90%',
|
|
||||||
type: '6',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
main: '指标 1.23',
|
|
||||||
value: 111,
|
|
||||||
percent: '90%',
|
|
||||||
type: '7',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
main: '指标 1.24',
|
|
||||||
value: 111,
|
|
||||||
percent: '90%',
|
|
||||||
type: '8',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
main: '指标 1.3',
|
|
||||||
value: 111,
|
|
||||||
percent: '90%',
|
|
||||||
type: '9',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
main: '指标 1.4',
|
|
||||||
value: 111,
|
|
||||||
percent: '90%',
|
|
||||||
type: '10',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
main: '指标 2',
|
|
||||||
value: 12312,
|
|
||||||
percent: '79%',
|
|
||||||
type: '11',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
main: '指标 3',
|
|
||||||
value: 12312,
|
|
||||||
percent: '79%',
|
|
||||||
type: '12',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
],
|
{
|
||||||
|
"name": "Consensus",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"name": "Models diversity",
|
||||||
|
"children": [
|
||||||
|
{ "name": "Different initializations" },
|
||||||
|
{ "name": "Different parameter choices" },
|
||||||
|
{ "name": "Different architectures" },
|
||||||
|
{ "name": "Different modeling methods" },
|
||||||
|
{ "name": "Different training sets" },
|
||||||
|
{ "name": "Different feature sets" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Methods",
|
||||||
|
"children": [
|
||||||
|
{ "name": "Classifier selection" },
|
||||||
|
{ "name": "Classifier fusion" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Common",
|
||||||
|
"children": [
|
||||||
|
{ "name": "Bagging" },
|
||||||
|
{ "name": "Boosting" },
|
||||||
|
{ "name": "AdaBoost" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Regression",
|
||||||
|
"children": [
|
||||||
|
{ "name": "Multiple linear regression" },
|
||||||
|
{ "name": "Partial least squares" },
|
||||||
|
{ "name": "Multi-layer feedforward neural network" },
|
||||||
|
{ "name": "General regression neural network" },
|
||||||
|
{ "name": "Support vector regression" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
};
|
};
|
||||||
const tree = new G6.Tree({
|
G6.registerNode('treeNode', {
|
||||||
container: 'mountNode',
|
anchor: [
|
||||||
height: 500,
|
[ 0.5, 0 ],
|
||||||
renderer: 'svg',
|
[ 0.5, 1 ]
|
||||||
layout: new G6.Layouts.CompactBoxTree({
|
]
|
||||||
// direction: 'LR', // 方向(LR/RL/H/TB/BT/V)
|
|
||||||
getHGap: function getHGap() /* d */ {
|
|
||||||
// 横向间距
|
|
||||||
return 20;
|
|
||||||
},
|
|
||||||
getVGap: function getVGap() /* d */ {
|
|
||||||
// 竖向间距
|
|
||||||
return 24;
|
|
||||||
},
|
|
||||||
direction: 'TB',
|
|
||||||
}),
|
|
||||||
fitView: 'tl',
|
|
||||||
});
|
});
|
||||||
tree.node({
|
G6.registerEdge('smooth', {
|
||||||
shape: 'card',
|
getPath(item) {
|
||||||
});
|
const points = item.getPoints();
|
||||||
tree.edge({
|
const start = points[0];
|
||||||
shape: 'polyline',
|
const end = points[points.length - 1];
|
||||||
});
|
const vgap = Math.abs(end.y - start.y);
|
||||||
tree.on('node:click', ev => {
|
return [
|
||||||
const { domEvent, item } = ev;
|
[ 'M', start.x, start.y ],
|
||||||
const { target } = domEvent;
|
[ 'C', start.x , start.y+ vgap / 2, end.x, end.y - vgap / 2, end.x, end.y ]
|
||||||
const { collapsed, type } = item.getModel();
|
];
|
||||||
const parent = item.getParent();
|
|
||||||
if (target.className === 'ce-button') {
|
|
||||||
if (collapsed) {
|
|
||||||
tree.update(item, {
|
|
||||||
collapsed: false,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
tree.update(item, {
|
|
||||||
collapsed: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 点击展开某个节点 同级其他节点收起
|
|
||||||
const children = parent && parent.getModel().children;
|
|
||||||
if (children && children.length > 0 && type) {
|
|
||||||
const isHideArr = children.filter(elem => type !== elem.type);
|
|
||||||
const isShowArr = children.filter(elem => type === elem.type);
|
|
||||||
isHideArr.forEach(element => {
|
|
||||||
tree.update(element.id, { collapsed: true });
|
|
||||||
});
|
|
||||||
isShowArr.forEach(element => {
|
|
||||||
tree.update(element.id, { collapsed: false });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
tree.read(data);
|
const layout = new G6.Layouts.Dendrogram({
|
||||||
|
"direction": "TB",
|
||||||
|
"rankSep": 200
|
||||||
|
});
|
||||||
|
const tree = new G6.Tree({
|
||||||
|
id: 'mountNode', // 容器ID
|
||||||
|
height: window.innerHeight, // 画布高
|
||||||
|
layout,
|
||||||
|
fitView: 'autoZoom' // 自动缩放
|
||||||
|
});
|
||||||
|
tree.node({
|
||||||
|
shape: 'treeNode',
|
||||||
|
size: 8,
|
||||||
|
label(model) {
|
||||||
|
if(model.children && model.children.length>0) {
|
||||||
|
return {
|
||||||
|
text: model.name,
|
||||||
|
textAlign: 'right'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
text: model.name,
|
||||||
|
textAlign: 'left'
|
||||||
|
};
|
||||||
|
},
|
||||||
|
labelRotate: Math.PI / 2,
|
||||||
|
labelOffsetX(model) {
|
||||||
|
if(model.children && model.children.length>0) {
|
||||||
|
return -10;
|
||||||
|
}
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tree.edge({
|
||||||
|
shape: 'smooth',
|
||||||
|
label: 'edge label',
|
||||||
|
labelRotate: Math.PI / 2,
|
||||||
|
});
|
||||||
|
tree.read({ roots: [data] });
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -98,7 +98,7 @@
|
|||||||
"screenshot": "node ./bin/screenshot.js",
|
"screenshot": "node ./bin/screenshot.js",
|
||||||
"start": "npm run dev",
|
"start": "npm run dev",
|
||||||
"test": "torch --compile --renderer --recursive ./test/unit",
|
"test": "torch --compile --renderer --recursive ./test/unit",
|
||||||
"test-live": "torch --compile --interactive --watch --recursive ./test/test-spec.js",
|
"test-live": "torch --compile --interactive --watch --recursive ./test/unit/item/*-spec.js",
|
||||||
"watch": "webpack --config webpack-dev.config.js",
|
"watch": "webpack --config webpack-dev.config.js",
|
||||||
"win-dev": "node ./bin/win-dev.js"
|
"win-dev": "node ./bin/win-dev.js"
|
||||||
},
|
},
|
||||||
|
@ -76,7 +76,7 @@ Shape.registerEdge('common', {
|
|||||||
let label = this.getLabel(item);
|
let label = this.getLabel(item);
|
||||||
const group = item.getGraphicGroup();
|
const group = item.getGraphicGroup();
|
||||||
const model = item.getModel();
|
const model = item.getModel();
|
||||||
const { labelOffsetX, labelOffsetY } = model;
|
const { labelOffsetX, labelOffsetY, labelRotate } = model;
|
||||||
if (label) {
|
if (label) {
|
||||||
const center = keyShape.getPoint(0.5);
|
const center = keyShape.getPoint(0.5);
|
||||||
if (!center) {
|
if (!center) {
|
||||||
@ -101,7 +101,7 @@ Shape.registerEdge('common', {
|
|||||||
fill: 'white'
|
fill: 'white'
|
||||||
};
|
};
|
||||||
const style = model.labelRectStyle ? Util.mix({}, defaultStyle, model.labelRectStyle) : defaultStyle;
|
const style = model.labelRectStyle ? Util.mix({}, defaultStyle, model.labelRectStyle) : defaultStyle;
|
||||||
group.addShape('rect', {
|
const rect = group.addShape('rect', {
|
||||||
attrs: Util.mix({}, style, {
|
attrs: Util.mix({}, style, {
|
||||||
x: textBox.minX - padding[3],
|
x: textBox.minX - padding[3],
|
||||||
y: textBox.minY - padding[0],
|
y: textBox.minY - padding[0],
|
||||||
@ -109,6 +109,22 @@ Shape.registerEdge('common', {
|
|||||||
height: textBox.maxY - textBox.minY + padding[0] + padding[2]
|
height: textBox.maxY - textBox.minY + padding[0] + padding[2]
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
if (labelRotate) {
|
||||||
|
const centerX = (textBox.maxX + textBox.minX) / 2;
|
||||||
|
const centerY = (textBox.maxY + textBox.minY) / 2;
|
||||||
|
|
||||||
|
// labelRotate
|
||||||
|
label.transform([
|
||||||
|
[ 't', -centerX, -centerY ],
|
||||||
|
[ 'r', labelRotate, labelRotate ],
|
||||||
|
[ 't', centerX, centerY ]
|
||||||
|
]);
|
||||||
|
rect.transform([
|
||||||
|
[ 't', -centerX, -centerY ],
|
||||||
|
[ 'r', labelRotate, labelRotate ],
|
||||||
|
[ 't', centerX, centerY ]
|
||||||
|
]);
|
||||||
|
}
|
||||||
Util.toFront(label);
|
Util.toFront(label);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -31,7 +31,7 @@ Shape.registerGroup('common', {
|
|||||||
x = x + margin[0];
|
x = x + margin[0];
|
||||||
y = y + margin[1];
|
y = y + margin[1];
|
||||||
const model = item.getModel();
|
const model = item.getModel();
|
||||||
const { labelOffsetX, labelOffsetY } = model;
|
const { labelOffsetX, labelOffsetY, labelRotate } = model;
|
||||||
x = labelOffsetX ? labelOffsetX + x : x;
|
x = labelOffsetX ? labelOffsetX + x : x;
|
||||||
y = labelOffsetY ? labelOffsetY + y : y;
|
y = labelOffsetY ? labelOffsetY + y : y;
|
||||||
const attrs = Util.mix(true, {}, Global.labelStyle, {
|
const attrs = Util.mix(true, {}, Global.labelStyle, {
|
||||||
@ -45,10 +45,13 @@ Shape.registerGroup('common', {
|
|||||||
} else {
|
} else {
|
||||||
Util.mix(attrs, label);
|
Util.mix(attrs, label);
|
||||||
}
|
}
|
||||||
group.addShape('text', {
|
const labelShape = group.addShape('text', {
|
||||||
class: 'label',
|
class: 'label',
|
||||||
attrs
|
attrs
|
||||||
});
|
});
|
||||||
|
if (labelRotate) {
|
||||||
|
labelShape.rotate(labelRotate);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
drawKeyShape(item, box) {
|
drawKeyShape(item, box) {
|
||||||
const { x, y, width, height } = box;
|
const { x, y, width, height } = box;
|
||||||
|
@ -53,7 +53,7 @@ Shape.registerNode('common', {
|
|||||||
const group = item.getGraphicGroup();
|
const group = item.getGraphicGroup();
|
||||||
const label = this.getLabel(item);
|
const label = this.getLabel(item);
|
||||||
const model = item.getModel();
|
const model = item.getModel();
|
||||||
const { labelOffsetX, labelOffsetY } = model;
|
const { labelOffsetX, labelOffsetY, labelRotate } = model;
|
||||||
if (Util.isNil(label)) {
|
if (Util.isNil(label)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -66,10 +66,14 @@ Shape.registerNode('common', {
|
|||||||
} else {
|
} else {
|
||||||
Util.mix(attrs, label);
|
Util.mix(attrs, label);
|
||||||
}
|
}
|
||||||
return group.addShape('text', {
|
const labelShape = group.addShape('text', {
|
||||||
class: 'label',
|
class: 'label',
|
||||||
attrs
|
attrs
|
||||||
});
|
});
|
||||||
|
if (labelRotate) {
|
||||||
|
labelShape.rotate(labelRotate);
|
||||||
|
}
|
||||||
|
return labelShape;
|
||||||
},
|
},
|
||||||
getPath(item) {
|
getPath(item) {
|
||||||
const size = this.getSize(item);
|
const size = this.getSize(item);
|
||||||
|
@ -28,7 +28,7 @@ describe('edge item test', () => {
|
|||||||
const edge = graph.find('node2->node1');
|
const edge = graph.find('node2->node1');
|
||||||
expect(edge.getTarget().id).equal('node1');
|
expect(edge.getTarget().id).equal('node1');
|
||||||
});
|
});
|
||||||
it('labeloffset', () => {
|
it('label offset', () => {
|
||||||
const edge = graph.find('node2->node1');
|
const edge = graph.find('node2->node1');
|
||||||
graph.update(edge, {
|
graph.update(edge, {
|
||||||
label: 'node2->node1',
|
label: 'node2->node1',
|
||||||
@ -38,6 +38,14 @@ describe('edge item test', () => {
|
|||||||
expect(edge.getLabel().attr('x')).to.almost.eql(162.23606797749977);
|
expect(edge.getLabel().attr('x')).to.almost.eql(162.23606797749977);
|
||||||
expect(edge.getLabel().attr('y')).to.almost.eql(136.11803398874991);
|
expect(edge.getLabel().attr('y')).to.almost.eql(136.11803398874991);
|
||||||
});
|
});
|
||||||
|
it('label rotate', () => {
|
||||||
|
const edge = graph.find('node2->node1');
|
||||||
|
graph.update(edge, {
|
||||||
|
label: 'node2->node1',
|
||||||
|
labelRotate: Math.PI / 2
|
||||||
|
});
|
||||||
|
expect(edge.getLabel().getMatrix()).to.almost.deep.eql([ 6.123233995736766e-17, 1, 0, -1, 6.123233995736766e-17, 0, 298.3541019662497, -26.118033988749858, 1 ]);
|
||||||
|
});
|
||||||
it('destroy', () => {
|
it('destroy', () => {
|
||||||
graph.destroy();
|
graph.destroy();
|
||||||
});
|
});
|
||||||
|
@ -32,7 +32,7 @@ describe('group item test', () => {
|
|||||||
it('getInnerEdges', () => {
|
it('getInnerEdges', () => {
|
||||||
expect(graph.find('group1').getInnerEdges().length).eql(2);
|
expect(graph.find('group1').getInnerEdges().length).eql(2);
|
||||||
});
|
});
|
||||||
it('labeloffset', () => {
|
it('label offset', () => {
|
||||||
const group = graph.find('group1');
|
const group = graph.find('group1');
|
||||||
graph.update(group, {
|
graph.update(group, {
|
||||||
label: 'group1',
|
label: 'group1',
|
||||||
@ -42,6 +42,14 @@ describe('group item test', () => {
|
|||||||
expect(group.getLabel().attr('x')).to.almost.eql(87.5);
|
expect(group.getLabel().attr('x')).to.almost.eql(87.5);
|
||||||
expect(group.getLabel().attr('y')).to.almost.eql(57.5);
|
expect(group.getLabel().attr('y')).to.almost.eql(57.5);
|
||||||
});
|
});
|
||||||
|
it('label rotate', () => {
|
||||||
|
const group = graph.find('group1');
|
||||||
|
graph.update(group, {
|
||||||
|
label: 'group1',
|
||||||
|
labelRotate: Math.PI / 2
|
||||||
|
});
|
||||||
|
expect(group.getLabel().getMatrix()).to.almost.deep.eql([ 6.123233995736766e-17, 1, 0, -1, 6.123233995736766e-17, 0, 0, 0, 1 ]);
|
||||||
|
});
|
||||||
it('destroy', () => {
|
it('destroy', () => {
|
||||||
graph.destroy();
|
graph.destroy();
|
||||||
});
|
});
|
||||||
|
@ -50,7 +50,7 @@ describe('node item test', () => {
|
|||||||
41
|
41
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('labeloffset', () => {
|
it('label offset', () => {
|
||||||
const node = graph.find('node1');
|
const node = graph.find('node1');
|
||||||
graph.update(node, {
|
graph.update(node, {
|
||||||
label: 'node1',
|
label: 'node1',
|
||||||
@ -60,6 +60,14 @@ describe('node item test', () => {
|
|||||||
expect(node.getLabel().attr('x')).to.almost.eql(10);
|
expect(node.getLabel().attr('x')).to.almost.eql(10);
|
||||||
expect(node.getLabel().attr('y')).to.almost.eql(10);
|
expect(node.getLabel().attr('y')).to.almost.eql(10);
|
||||||
});
|
});
|
||||||
|
it('label rotate', () => {
|
||||||
|
const node = graph.find('node2');
|
||||||
|
graph.update(node, {
|
||||||
|
label: 'node2',
|
||||||
|
labelRotate: Math.PI / 2
|
||||||
|
});
|
||||||
|
expect(node.getLabel().getMatrix()).to.almost.deep.eql([ 6.123233995736766e-17, 1, 0, -1, 6.123233995736766e-17, 0, 0, 0, 1 ]);
|
||||||
|
});
|
||||||
it('destroy', () => {
|
it('destroy', () => {
|
||||||
graph.destroy();
|
graph.destroy();
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user