add default image node

This commit is contained in:
zhanning.bzn 2019-09-29 18:15:27 +08:00
parent 701abd629a
commit 901008f523
6 changed files with 276 additions and 29 deletions

93
demos/imageNode.html Normal file
View File

@ -0,0 +1,93 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>默认的图片节点</title>
</head>
<body>
<div id="mountNode"></div>
<script src="../build/g6.js"></script>
<script>
const data = {
nodes: [
{
id: 'triangle',
label: '主题 ModelRect Title',
description: '这里是一顿描述信息,不知道长短',
x: 150,
y: 100
}
]
}
const graph = new G6.Graph({
container: 'mountNode',
width: 800,
height: 600,
defaultNode: {
shape: 'image',
size: [200, 80],
labelCfg:{
position: 'right',
offset: -120
},
clipCfg: {
show: true,
type: 'path',
width: 15,
height: 15
}
},
nodeStateStyles: {
select: {
fill: 'red'
},
hover: {
fill: 'blue'
}
},
modes: {
default: ['drag-canvas']
}
})
graph.data(data)
graph.render()
graph.on('node:click', evt => {
const { item } = evt
graph.setItemState(item, 'select', true)
graph.updateItem(item, {
size: [ 160, 130],
style: {
fill: '#b5f5ec'
},
preRect: {
fill: '#ff4d4f'
},
linkPoints: {
fill: '#fff',
size: 5
},
stateIcon: {
img: 'https://gw.alipayobjects.com/zos/basement_prod/c781088a-c635-452a-940c-0173663456d4.svg'
}
})
})
graph.on('node:mouseenter', evt => {
const { item } = evt
graph.setItemState(item, 'hover', true)
})
graph.on('node:mouseleave', evt => {
const { item } = evt
graph.setItemState(item, 'hover', false)
})
</script>
</body>
</html>

View File

@ -19,6 +19,19 @@
description: '这里是一顿描述信息,不知道长短',
x: 150,
y: 100
},
{
id: 'triangle1',
label: 'Test ModelRect Title',
description: '这里是一顿描述信息,不知道长短',
x: 350,
y: 130
}
],
edges: [
{
source: 'triangle',
target: 'triangle1'
}
]
}
@ -28,9 +41,6 @@
height: 600,
defaultNode: {
shape: 'modelRect',
style: {
fill: 'red'
},
icon: {
show: true,
width: 30,
@ -42,6 +52,13 @@
size: 5
}
},
defaultEdge: {
shape: 'quadratic',
style: {
stroke: 'red',
lineWidth: 3
}
},
nodeStateStyles: {
select: {
fill: 'red'
@ -54,7 +71,7 @@
// 这里优先级大于graph中的nodeStyle
graph.node(node => {
let fill = 'red'
let fill = '#36cfc9'
let shape = 'diamond'
if (node.inDegree > 200) {
fill = '#36cfc9'
@ -62,6 +79,7 @@
}
return {
shape,
labelPosition: 'bottom',
icon: {
show: true,
width: 25,
@ -71,6 +89,9 @@
top: true,
bottom: true
},
labelCfg: {
position: 'bottom'
},
style: {
fill,
stroke: '#eaff8f',
@ -78,7 +99,7 @@
},
stateStyles: {
hover: {
fill: '#bae637',
// fill: '#bae637',
stroke: '#87e8de',
width: 130,
height: 200,
@ -97,6 +118,7 @@
graph.on('node:click', evt => {
const { item } = evt
graph.setItemState(item, 'select', true)
debugger
graph.updateItem(item, {
size: [ 160, 130],
style: {
@ -105,6 +127,10 @@
preRect: {
fill: '#ff4d4f'
},
linkPoints: {
fill: '#fff',
size: 5
},
stateIcon: {
img: 'https://gw.alipayobjects.com/zos/basement_prod/c781088a-c635-452a-940c-0173663456d4.svg'
}

View File

@ -87,13 +87,14 @@ class ItemController {
// 如果修改了与映射属性有关的数据项,映射的属性相应也需要变化
const mapper = graph.get(item.getType() + MAPPER_SUFFIX);
if (mapper) {
const newModel = Util.mix({}, item.getModel(), cfg);
const mappedModel = mapper(newModel);
if (mappedModel.styles) {
item.set('styles', mappedModel.styles);
delete mappedModel.styles;
const model = item.getModel();
const mappedModel = mapper(model);
const newModel = Util.mix({}, mappedModel, cfg);
if (mappedModel[STATE_SUFFIX]) {
item.set('styles', newModel[STATE_SUFFIX]);
delete newModel[STATE_SUFFIX];
}
Util.each(mappedModel, (val, key) => {
Util.each(newModel, (val, key) => {
cfg[key] = val;
});
}

View File

@ -99,22 +99,22 @@ Shape.registerNode('single-shape', singleNodeDefinition);
/**
* 基本的图片可以添加文本默认文本在图片的下面
*/
Shape.registerNode('image', {
shapeType: 'image',
labelPosition: 'bottom',
getShapeStyle(cfg) {
const size = this.getSize(cfg);
const img = cfg.img;
const width = size[0];
const height = size[1];
const style = Util.mix({}, {
x: 0 - width / 2, // 节点的位置在上层确定,所以这里仅使用相对位置即可
y: 0 - height / 2,
width,
height,
img
}, cfg.style);
return style;
}
}, 'single-shape');
// Shape.registerNode('image', {
// shapeType: 'image',
// labelPosition: 'bottom',
// getShapeStyle(cfg) {
// const size = this.getSize(cfg);
// const img = cfg.img;
// const width = size[0];
// const height = size[1];
// const style = Util.mix({}, {
// x: 0 - width / 2, // 节点的位置在上层确定,所以这里仅使用相对位置即可
// y: 0 - height / 2,
// width,
// height,
// img
// }, cfg.style);
// return style;
// }
// }, 'single-shape');

126
src/shape/nodes/image.js Normal file
View File

@ -0,0 +1,126 @@
const Shape = require('../shape');
const Util = require('../../util/index');
const G = require('@antv/g');
/**
* 基本的图片可以添加文本默认文本在图片的下面
*/
Shape.registerNode('image', {
options: {
img: 'https://img2.bosszhipin.com/boss/avatar/avatar_13.png',
size: 200,
clipCfg: {
show: false,
type: 'circle',
// circle
r: 15,
// ellipse
rx: 10,
ry: 15,
// rect
width: 15,
height: 15,
// polygon
points: [
[ 30, 12 ],
[ 12, 30 ],
[ 30, 48 ],
[ 48, 30 ]
],
// path
path: [
[ 'M', 25, 25 ],
[ 'L', 50, 25 ],
[ 'A', 25 / 2, 25 / 2, 0, 1, 1, 50, 50 ],
[ 'A', 25 / 2, 25 / 2, 0, 1, 0, 50, 50 ],
[ 'L', 25, 75 ],
[ 'Z' ]
],
// 坐标
x: 0,
y: 0
}
},
shapeType: 'image',
labelPosition: 'bottom',
drawShape(cfg, group) {
const shapeType = this.shapeType; // || this.type都已经加了 shapeType
const style = this.getShapeStyle(cfg);
const shape = group.addShape(shapeType, {
attrs: style
});
this.drawClip(cfg, shape);
return shape;
},
drawClip(cfg, shape) {
const clip = Util.mix({}, this.options.clipCfg, cfg.clipCfg);
if (!clip.show) {
return;
}
// 支持circle、rect、ellipse、Polygon及自定义path clip
const { type, x, y } = clip;
let clipShape = null;
if (type === 'circle') {
const { r } = clip;
clipShape = new G.Circle({
attrs: {
r,
x,
y
}
});
} else if (type === 'rect') {
const { width, height } = clip;
clipShape = new G.Rect({
attrs: {
x,
y,
width,
height
}
});
} else if (type === 'ellipse') {
const { rx, ry } = clip;
clipShape = new G.Ellipse({
attrs: {
x,
y,
rx,
ry
}
});
} else if (type === 'polygon') {
const { points } = clip;
clipShape = new G.Polygon({
attrs: {
points
}
});
} else if (type === 'path') {
const { path } = clip;
clipShape = new G.Path({
attrs: {
path
}
});
}
if (clipShape) {
shape.attr('clip', clipShape);
}
},
getShapeStyle(cfg) {
const size = this.getSize(cfg);
const img = cfg.img || this.options.img;
const width = size[0];
const height = size[1];
const style = Util.mix({}, {
x: 0 - width / 2, // 节点的位置在上层确定,所以这里仅使用相对位置即可
y: 0 - height / 2,
width,
height,
img
}, cfg.style);
return style;
}
}, 'single-shape');

View File

@ -5,3 +5,4 @@ require('./diamond');
require('./triangle');
require('./modelRect');
require('./star');
require('./image');