This commit is contained in:
TomHuangCN 2018-08-23 11:15:49 +08:00
parent ac24eb6acd
commit 1b65963608
8 changed files with 113 additions and 67 deletions

View File

@ -5,59 +5,72 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="./assets/jquery-3.2.1.min.js"></script>
<script src="../build/g6.js"></script>
<script src="../build/plugin.layout.forceAtlas2.js"></script>
<script src="../build/plugin.layout.circle.js"></script>
<script src="../build/plugin.util.dataCleaner.js"></script>
<script src="../build/plugin.layout.dagre.js"></script>
<script src="../build/plugin.tool.tooltip.js"></script>
<title>测试</title>
</head>
<body>
<div id="mountNode"></div>
<script src="../build/g6.js"></script>
<script>
// 详细文档见 https://antv.alipay.com/g6/doc/index.html
const data = {"name":"Modeling Methods","children":[{"name":"Classification","children":[{"name":"Logistic regression"},{"name":"Linear discriminant analysis"},{"name":"Rules"},{"name":"Decision trees"},{"name":"Naive Bayes"},{"name":"K nearest neighbor"},{"name":"Probabilistic neural network"},{"name":"Support vector machine"}]},{"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"}]}]};
var layout = new G6.Layouts.CompactBoxTree({
// direction: 'LR', // 方向LR/RL/H/TB/BT/V
getHGap: function getHGap() /* d */ {
// 横向间距
return 100;
},
getVGap: function getVGap() /* d */ {
// 竖向间距
return 10;
const plugin = new G6.Plugins['tool.tooltip']();
const data = {
nodes: [{
id: 'node1',
x: 100,
y: 200,
title: 'aaa',
}, {
id: 'node2',
x: 300,
y: 200,
title: 'bbb',
}],
edges: [{
target: 'node2',
source: 'node1',
}]
};
const graph = new G6.Graph({
container: 'mountNode',
width: 500,
height: 500,
plugins: [ plugin ]
});
graph.node({
tooltip(model) {
return [
['id', model.id],
['x', model.x],
['y', model.y],
['标题', model.title]
];
},
label(model) {
return model.title;
}
});
var tree = new G6.Tree({
id: 'mountNode', // 容器ID
height: window.innerHeight, // 画布高
layout: layout,
fitView: 'autoZoom', // 自动缩放
graph.edge({
tooltip(model) {
return [
['来源', model.source],
['去向', model.target],
['标题', model.title]
];
}
});
tree
.node({
shape: 'treeNode',
size: 8,
})
tree.edge({
shape: 'smooth',
});
tree.on('node:mouseenter', ev => {
console.log('mouseenter')
tree.simpleUpdate(ev.item, {
color: 'orange',
graph.read(data);
setTimeout(()=>{
console.log(22)
graph.update('node1', {
title: 'sss'
});
});
tree.on('node:mouseleave', ev => {
console.log('mouseleave')
tree.simpleUpdate(ev.item, {
color: 'blue',
});
});
tree.read({
roots: [data],
});
}, 1000);
</script>
</body>
</html>

View File

@ -6,7 +6,9 @@ class ForceCalculator {
updateNodesByForces(data) {
let { nodes, edges, maxIteration, barnesHut, prune } = data;
edges = edges.filter(edge => {
return edge.source !== edge.target;
});
const size = nodes.length;
const esize = edges.length;
@ -27,6 +29,7 @@ class ForceCalculator {
let node2;
let sIdx = 0,
tIdx = 0;
for (let j = 0; j < size; j += 1) {
if (nodes[j].id === edges[i].source) {
node1 = nodes[j];

View File

@ -35,12 +35,12 @@ class Plugin {
const graph = this.graph;
Util.each(freezeElements, freezeElement => {
const freezePoint = freezeElement.get('freezePoint');
const scale = graph.getScale();
const zoom = graph.getZoom();
if (freezeElement.isShape && freezePoint && freezeElement.get('visible')) {
freezeElement.resetMatrix();
freezeElement.transform([
[ 't', -freezePoint.x, -freezePoint.y ],
[ 's', 1 / scale, 1 / scale ],
[ 's', 1 / zoom, 1 / zoom ],
[ 't', freezePoint.x, freezePoint.y ]
]);
}

View File

@ -27,8 +27,8 @@ class Plugin {
Util.each(nodes, node => {
const label = node.getLabel();
const labelBox = label.getBBox();
const scale = graph.getScale();
const labelWidth = (labelBox.maxX - labelBox.minX) * (1 / scale);
const zoom = graph.getZoom();
const labelWidth = (labelBox.maxX - labelBox.minX) * (1 / zoom);
const nodeBox = node.getBBox();
const nodeWidth = nodeBox.maxX - nodeBox.minX;

View File

@ -0,0 +1,34 @@
/**
* @fileOverview clean data
* @author huangtonger@aliyun.com
*/
const G6 = require('@antv/g6');
const Util = G6.Util;
const dataCleaner = {
clearData(data) {
const nodeMap = {};
const invalidEdges = [];
data.nodes.forEach(node => {
nodeMap[node.id] = node;
});
data.edges.forEach(edge => {
// console.log(edge, nodeMap[edge.source], nodeMap[edge.target]);
if (!nodeMap[edge.source]) {
console.warn('remove ', edge, 'because there is no source node');
invalidEdges.push(edge);
return;
}
if (!nodeMap[edge.target]) {
console.warn('remove ', edge, 'because there is no target node');
invalidEdges.push(edge);
return;
}
});
data.edges = data.edges.filter(edge => {
return invalidEdges.indexOf(edge) === -1;
});
}
};
Util.mix(Util, dataCleaner);

View File

@ -60,15 +60,17 @@ class Edge extends Item {
_addArrow() {
const model = this.model;
const keyShape = this.keyShape;
const shapeObj = this.shapeObj;
const styleEndArrow = keyShape.attr('endArrow');
const styleStartArrow = keyShape.attr('startArrow');
const endArrow = model.endArrow || styleEndArrow;
const startArrow = model.startArrow || styleStartArrow;
styleStartArrow && keyShape.attr('startArrow', false);
styleEndArrow && keyShape.attr('endArrow', false);
endArrow && this._drawArrow(shapeObj.endArrow, 'end');
startArrow && this._drawArrow(shapeObj.startArrow, 'start');
if (keyShape.get('type') === 'path') {
const shapeObj = this.shapeObj;
const styleEndArrow = keyShape.attr('endArrow');
const styleStartArrow = keyShape.attr('startArrow');
const endArrow = model.endArrow || styleEndArrow;
const startArrow = model.startArrow || styleStartArrow;
styleStartArrow && keyShape.attr('startArrow', false);
styleEndArrow && keyShape.attr('endArrow', false);
endArrow && this._drawArrow(shapeObj.endArrow, 'end');
startArrow && this._drawArrow(shapeObj.startArrow, 'start');
}
}
_drawArrow({ path, dindent, tangent, ratio, style }, type) {
tangent = tangent(this);

View File

@ -189,12 +189,6 @@ Mixin.AUGMENT = {
const rootGroup = this.get('_rootGroup');
return rootGroup.getMatrix();
},
/**
* @return {number} scale
*/
getScale() {
return this.getMatrix()[0];
},
/**
* @param {object} matrix - matrix
*/

View File

@ -12,14 +12,14 @@ const defaultArrow = {
const keyShape = item.getKeyShape();
let lineWidth = keyShape.attr('lineWidth');
lineWidth = lineWidth > MIN_ARROW_SIZE ? lineWidth : MIN_ARROW_SIZE;
const halfWidth = lineWidth * 10 / 3;
const width = lineWidth * 10 / 3;
const halfHeight = lineWidth * 4 / 3;
const radius = lineWidth * 4;
return [
[ 'M', -halfWidth, halfHeight ],
[ 'M', -width, halfHeight ],
[ 'L', 0, 0 ],
[ 'L', -halfWidth, -halfHeight ],
[ 'A', radius, radius, 0, 0, 1, -halfWidth, halfHeight ],
[ 'L', -width, -halfHeight ],
[ 'A', radius, radius, 0, 0, 1, -width, halfHeight ],
[ 'Z' ]
];
},