mirror of
https://gitee.com/antv/g6.git
synced 2024-12-10 07:38:18 +08:00
253 lines
7.4 KiB
HTML
253 lines
7.4 KiB
HTML
<!DOCTYPE html></script>
|
||
<html lang="en">
|
||
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<title>data process</title>
|
||
<style>
|
||
canvas{
|
||
background: rgb(0, 0, 0);
|
||
background-image: url("./assets/data/background-small.png");
|
||
/* background-repeat: no-repeat; */
|
||
background-size: 600px 600px;
|
||
}
|
||
.g6-tooltip {
|
||
border: 1px solid #e2e2e2;
|
||
border-radius: 4px;
|
||
font-size: 12px;
|
||
color: #545454;
|
||
background-color: rgba(255, 255, 255, 0.9);
|
||
padding: 10px 8px;
|
||
box-shadow: rgb(174, 174, 174) 0px 0px 10px;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div id="mountNode"></div>
|
||
<script src="../build/g6.js"></script>
|
||
<script src="./assets/jquery-3.2.1.min.js"></script>
|
||
<script>
|
||
|
||
const colors = [ 'rgb(64, 174, 247)', 'rgb(108, 207, 169)', 'rgb(157, 223, 125)',
|
||
'rgb(240, 198, 74)', 'rgb(221, 158, 97)', 'rgb(141, 163, 112)', 'rgb(115, 136, 220)',
|
||
'rgb(133, 88, 219)', 'rgb(203, 135, 226)', 'rgb(227, 137, 163)' ];
|
||
// custom the node
|
||
G6.registerNode('breath-node', {
|
||
afterDraw(cfg, group) {
|
||
const r = cfg.size / 2;
|
||
console.log(cfg);
|
||
const back1 = group.addShape('circle', {
|
||
zIndex: -3,
|
||
attrs: {
|
||
x: 0,
|
||
y: 0,
|
||
r,
|
||
fill: cfg.color || (cfg.style && cfg.style.fill),
|
||
opacity: 0.6
|
||
}
|
||
});
|
||
const back2 = group.addShape('circle', {
|
||
zIndex: -2,
|
||
attrs: {
|
||
x: 0,
|
||
y: 0,
|
||
r,
|
||
fill: cfg.color,
|
||
// 为了显示清晰,随意设置了颜色
|
||
opacity: 0.6
|
||
}
|
||
});
|
||
const back3 = group.addShape('circle', {
|
||
zIndex: -1,
|
||
attrs: {
|
||
x: 0,
|
||
y: 0,
|
||
r,
|
||
fill: cfg.color,
|
||
opacity: 0.6
|
||
}
|
||
});
|
||
group.sort(); // 排序,根据zIndex 排序
|
||
const delayBase = Math.random() * 2000;
|
||
back1.animate({ // 逐渐放大,并消失
|
||
r: r + 10,
|
||
opacity: 0.0,
|
||
repeat: true // 循环
|
||
},
|
||
3000, 'easeCubic', null, delayBase) // 无延迟
|
||
back2.animate({ // 逐渐放大,并消失
|
||
r: r + 10,
|
||
opacity: 0.0,
|
||
repeat: true // 循环
|
||
},
|
||
3000, 'easeCubic', null, delayBase + 1000) // 1 秒延迟
|
||
back3.animate({ // 逐渐放大,并消失
|
||
r: r + 10,
|
||
opacity: 0.0,
|
||
repeat: true // 循环
|
||
},
|
||
3000, 'easeCubic', null, delayBase + 2000) // 2 秒延迟
|
||
}
|
||
},
|
||
'circle');
|
||
|
||
// custom the edge
|
||
G6.registerEdge('running-polyline', {
|
||
afterDraw(cfg, group) {
|
||
const shape = group.get('children')[0];
|
||
const length = shape.getTotalLength();
|
||
const startPoint = shape.getPoint(0);
|
||
let circleCount = Math.ceil(length / 20);
|
||
circleCount = circleCount === 0 ? 1 : circleCount;
|
||
for (let i = 0; i < circleCount; i++) {
|
||
const delay = Math.random() * 1000;
|
||
const start = shape.getPoint(i / circleCount);
|
||
const circle = group.addShape('circle', {
|
||
attrs: {
|
||
x: start.x,
|
||
y: start.y,
|
||
r: 0.8,
|
||
fill: '#A0F3AF',
|
||
shadowColor: '#fff',
|
||
shadowBlur: 30,
|
||
}
|
||
});
|
||
circle.animate({
|
||
onFrame(ratio) {
|
||
ratio += i / circleCount;
|
||
if (ratio > 1) {
|
||
ratio %= 1;
|
||
}
|
||
const tmpPoint = shape.getPoint(ratio);
|
||
return {
|
||
x: tmpPoint.x,
|
||
y: tmpPoint.y
|
||
};
|
||
},
|
||
repeat: true
|
||
}, 10 * length, 'easeCubic', null, delay);
|
||
}
|
||
}
|
||
},
|
||
'polyline');
|
||
|
||
const graphSize = [ 600, 600 ];
|
||
const graph = new G6.Graph({
|
||
container: 'mountNode',
|
||
width: graphSize[0],
|
||
height: graphSize[1],
|
||
modes: {
|
||
default: [{
|
||
type: 'edge-tooltip',
|
||
formatText(model) {
|
||
const text = model.class;
|
||
return text;
|
||
},
|
||
shouldUpdate: e => {
|
||
return true;
|
||
}
|
||
}]
|
||
},
|
||
defaultNode: {
|
||
shape: 'breath-node',
|
||
size: 3,
|
||
style: {
|
||
lineWidth: 0,
|
||
fill: 'rgb(240, 223, 83)'
|
||
}
|
||
},
|
||
defaultEdge: {
|
||
shape: 'running-polyline',
|
||
size: 1,
|
||
color: 'rgb(14,142,63)',
|
||
style: {
|
||
opacity: 0.4,
|
||
lineAppendWidth: 3
|
||
}
|
||
},
|
||
nodeStyle: {
|
||
default: {
|
||
lineWidth:
|
||
2,
|
||
fill: '#fff'
|
||
},
|
||
click: {
|
||
fill: '#0f0'
|
||
}
|
||
}
|
||
});
|
||
graph.on('node:click', e => {
|
||
const item = e.item;
|
||
const model = item.get('model');
|
||
graph.setItemState(item, 'click', true);
|
||
});
|
||
$.getJSON('./assets/data/beijing-metro-lines.json', data => {
|
||
const nodes = data.nodes;
|
||
const edges = data.edges;
|
||
const classMap = new Map();
|
||
let classId = 0;
|
||
nodes.forEach(node => {
|
||
node.y = -node.y;
|
||
});
|
||
edges.forEach(edge => {
|
||
// edge cluster
|
||
if (edge.class && classMap.get(edge.class) === undefined) {
|
||
classMap.set(edge.class, classId);
|
||
classId ++;
|
||
}
|
||
const cid = classMap.get(edge.class);
|
||
edge.color = colors[cid % colors.length];
|
||
const controlPoints = edge.controlPoints;
|
||
|
||
controlPoints.forEach(cp => {
|
||
cp.y = -cp.y;
|
||
});
|
||
})
|
||
scaleNodesPoints(nodes, edges, graphSize);
|
||
graph.data(data);
|
||
graph.render();
|
||
});
|
||
|
||
function scaleNodesPoints(nodes, edges, graphSize) {
|
||
const size = graphSize[0] < graphSize[1] ? graphSize[0] : graphSize[1];
|
||
let minX = 99999999999999999;
|
||
let maxX = -99999999999999999;
|
||
let minY = 99999999999999999;
|
||
let maxY = -99999999999999999;
|
||
nodes.forEach(node => {
|
||
if (node.x > maxX) maxX = node.x;
|
||
if (node.x < minX) minX = node.x;
|
||
if (node.y > maxY) maxY = node.y;
|
||
if (node.y < minY) minY = node.y;
|
||
});
|
||
|
||
edges.forEach(edge => {
|
||
const controlPoints = edge.controlPoints;
|
||
controlPoints.forEach(cp => {
|
||
if (cp.x > maxX) maxX = cp.x;
|
||
if (cp.x < minX) minX = cp.x;
|
||
if (cp.y > maxY) maxY = cp.y;
|
||
if (cp.y < minY) minY = cp.y;
|
||
});
|
||
});
|
||
|
||
const xScale = maxX - minX;
|
||
const yScale = maxY - minY;
|
||
nodes.forEach(node => {
|
||
node.orix = node.x;
|
||
node.oriy = node.y;
|
||
node.x = (node.x - minX) / xScale * size;
|
||
node.y = (node.y - minY) / yScale * size;
|
||
});
|
||
edges.forEach(edge => {
|
||
const controlPoints = edge.controlPoints;
|
||
controlPoints.forEach(cp => {
|
||
cp.x = (cp.x - minX) / xScale * size;
|
||
cp.y = (cp.y - minY) / yScale * size;
|
||
});
|
||
});
|
||
}
|
||
</script>
|
||
</body>
|
||
|
||
</html> |