feat(minimap): add minimap

This commit is contained in:
yilin.qyl 2019-03-21 10:27:45 +08:00
parent 51d7af6913
commit 47ab748575
5 changed files with 49 additions and 32 deletions

View File

@ -9,7 +9,15 @@
<button id="download">点击下载图片</button> <button id="download">点击下载图片</button>
<script src="assets/hierarchy.js"></script> <script src="assets/hierarchy.js"></script>
<script src="../build/g6.js"></script> <script src="../build/g6.js"></script>
<script src="../build/minimap.js"></script>
<script src="./assets/jquery-3.2.1.min.js"></script> <script src="./assets/jquery-3.2.1.min.js"></script>
<style>
.g6-minimap{
position: absolute;
right: 0;
bottom: 0;
}
</style>
<script> <script>
const COLLAPSE_ICON = function(x, y, r) { const COLLAPSE_ICON = function(x, y, r) {
return [ return [
@ -70,10 +78,12 @@ G6.registerNode('tree-node', {
return rect; return rect;
} }
}, 'single-shape'); }, 'single-shape');
const minimap = new Minimap({ size: [200, 150] });
const graph = new G6.TreeGraph({ const graph = new G6.TreeGraph({
container: 'mountNode', container: 'mountNode',
width: 800, width: 800,
height: 600, height: 600,
plugins: [ minimap ],
modes: { modes: {
default: [{ default: [{
type: 'collapse-expand', type: 'collapse-expand',
@ -88,7 +98,7 @@ const graph = new G6.TreeGraph({
data.collapsed = collapsed; data.collapsed = collapsed;
return true; return true;
} }
}, 'drag-canvas'] }, 'drag-canvas', 'zoom-canvas']
}, },
defaultNode: { defaultNode: {
shape: 'tree-node', shape: 'tree-node',

View File

@ -7,6 +7,7 @@
<body> <body>
<div id="mountNode"></div> <div id="mountNode"></div>
<script src="../build/g6.js"></script> <script src="../build/g6.js"></script>
<script src="../build/minimap.js"></script>
<script> <script>
G6.registerEdge('relation', { G6.registerEdge('relation', {
@ -71,15 +72,16 @@
} }
}); });
return keyShape; return keyShape;
console.log(point, tangent);
} }
}); });
const minimap = new Minimap({ size: [ 160, 100 ] });
const graph = new G6.Graph({ const graph = new G6.Graph({
container: 'mountNode', container: 'mountNode',
width: 800, width: 800,
height: 500, height: 500,
plugins: [ minimap ],
modes: { modes: {
default: [ 'drag-node'] default: [ 'drag-node', 'drag-canvas', 'zoom-canvas']
} }
}); });
const data = { const data = {

View File

@ -110,7 +110,7 @@
"silent": false "silent": false
}, },
"dependencies": { "dependencies": {
"@antv/g": "~3.4.0", "@antv/g": "~3.4.1",
"@antv/util": "~1.3.1" "@antv/util": "~1.3.1"
}, },
"engines": { "engines": {

View File

@ -19,14 +19,6 @@ class Minimap extends Base {
className: 'g6-minimap', className: 'g6-minimap',
viewportClassName: 'g6-minimap-viewport', viewportClassName: 'g6-minimap-viewport',
keyShapeOnly: false, keyShapeOnly: false,
viewportStyle: {
stroke: '#1890ff',
lineWidth: 2,
x: 0,
y: 0,
width: 200,
height: 120
},
size: [ 200, 120 ] size: [ 200, 120 ]
}; };
} }
@ -146,16 +138,21 @@ class Minimap extends Base {
} else { } else {
this._updateGraphShapes(); this._updateGraphShapes();
} }
// 更新minimap视口
this._updateViewport();
// 刷新后bbox可能会变需要重置画布矩阵以缩放到合适的大小
const bbox = canvas.getBBox(); const bbox = canvas.getBBox();
// 刷新后bbox可能会变需要重置画布矩阵以缩放到合适的大小
const width = max(bbox.width, graph.get('width')); const width = max(bbox.width, graph.get('width'));
const height = max(bbox.height, graph.get('height')); const height = max(bbox.height, graph.get('height'));
const pixelRatio = canvas.get('pixelRatio'); const pixelRatio = canvas.get('pixelRatio');
const ratio = Math.min(size[0] / width, size[1] / height);
canvas.resetMatrix(); canvas.resetMatrix();
canvas.scale(size[0] / width * pixelRatio, size[1] / height * pixelRatio); canvas.scale(ratio * pixelRatio, ratio * pixelRatio);
// 缩放到适合视口后, 平移到画布中心
const dx = (size[0] - width * ratio) / 2;
const dy = (size[1] - height * ratio) / 2;
canvas.translate(dx * pixelRatio, dy * pixelRatio);
canvas.draw(); canvas.draw();
// 更新minimap视口
this._updateViewport(ratio, dx, dy);
} }
// 仅在minimap上绘制keyShape // 仅在minimap上绘制keyShape
// FIXME 如果用户自定义绘制了其他内容minimap上就无法画出 // FIXME 如果用户自定义绘制了其他内容minimap上就无法画出
@ -179,8 +176,7 @@ class Minimap extends Base {
} }
// 将主图上的图形完全复制到小图 // 将主图上的图形完全复制到小图
_updateGraphShapes() { _updateGraphShapes() {
const cfgs = this._cfgs; const graph = this.get('graph');
const graph = cfgs.graph;
const canvas = this.get('canvas'); const canvas = this.get('canvas');
const graphGroup = graph.get('group'); const graphGroup = graph.get('group');
const clonedGroup = graphGroup.clone(); const clonedGroup = graphGroup.clone();
@ -188,23 +184,32 @@ class Minimap extends Base {
canvas.get('children')[0] = clonedGroup; canvas.get('children')[0] = clonedGroup;
} }
// 绘制minimap视口 // 绘制minimap视口
_updateViewport() { _updateViewport(ratio, dx, dy) {
const size = this._cfgs.size; const graph = this.get('graph');
const graph = this._cfgs.graph; const size = this.get('size');
const matrix = graph.get('group').getMatrix(); const graphWidth = graph.get('width');
const graphHeight = graph.get('height');
const topLeft = graph.getPointByCanvas(0, 0); const topLeft = graph.getPointByCanvas(0, 0);
const bottomRight = graph.getPointByCanvas(graphWidth, graphHeight);
const viewport = this.get('viewport'); const viewport = this.get('viewport');
if (!viewport) { if (!viewport) {
this.initViewport(); this.initViewport();
} }
// viewport宽高,左上角点的计算 // viewport宽高,左上角点的计算
const width = matrix[0] >= 1 ? size[0] / matrix[0] : size[0]; let width = (bottomRight.x - topLeft.x) * ratio;
const height = matrix[4] >= 1 ? size[1] / matrix[4] : size[1]; let height = (bottomRight.y - topLeft.y) * ratio;
const left = topLeft.x > 0 ? topLeft.x * size[0] / graph.get('width') : 0; const left = topLeft.x * ratio + dx;
const top = topLeft.y > 0 ? topLeft.y * size[1] / graph.get('height') : 0; const top = topLeft.y * ratio + dy;
if (width > size[0]) {
width = size[0];
}
if (height > size[1]) {
height = size[1];
}
modifyCSS(viewport, { modifyCSS(viewport, {
left: left + 'px', left: left > 0 ? left + 'px' : 0,
top: top + 'px', top: top > 0 ? top + 'px' : 0,
width: width + 'px', width: width + 'px',
height: height + 'px' height: height + 'px'
}); });

View File

@ -49,14 +49,14 @@ describe('tooltip', () => {
expect(style.left).to.equal('64px'); expect(style.left).to.equal('64px');
expect(style.top).to.equal('64px'); expect(style.top).to.equal('64px');
graph.emit('node:mouseenter', { x: 410, y: 52, item: rt }); graph.emit('node:mouseenter', { x: 410, y: 52, item: rt });
expect(style.left).to.equal('372.203px'); expect(style.left).to.equal('384.203px');
expect(style.top).to.equal('64px'); expect(style.top).to.equal('64px');
graph.emit('node:mouseenter', { x: 410, y: 410, item: rb }); graph.emit('node:mouseenter', { x: 410, y: 410, item: rb });
expect(style.left).to.equal('372.203px'); expect(style.left).to.equal('384.203px');
expect(style.top).to.equal('380px'); expect(style.top).to.equal('392px');
graph.emit('node:mouseenter', { x: 52, y: 410, item: lb }); graph.emit('node:mouseenter', { x: 52, y: 410, item: lb });
expect(style.left).to.equal('64px'); expect(style.left).to.equal('64px');
expect(style.top).to.equal('380px'); expect(style.top).to.equal('392px');
graph.removeBehaviors('tooltip', 'default'); graph.removeBehaviors('tooltip', 'default');
div.removeChild(tooltip); div.removeChild(tooltip);
}); });