HTML节点可扩展性强,能实现比较好的交互,但是缩放功能比较受限,于是想到了canvas节点,但是canvas节点使用比较受限制,怎么能实现复杂一点的布局呢,又能交互起来,比如下图:
文字布局比较多,样式也不一样,然后能点击+弹出自定义菜单

/* 节点图形注册 */
registerNodes() {
let _this = this;
G6.registerNode("appNode", {
draw(cfg, group) {
const model = cfg.model;
let appColor = _this.getColor(model.status);
let size = cfg.size;
let aWidth = 80;
let aHeigth = 80;
if (size) {
//aWidth = aHeigth = size[0] > size[1] ? size[0] : size[1];
aWidth = size[0];
aHeigth = size[1];
}
const shape = group.addShape("rect", {
attrs: {
x: cfg.x,
y: cfg.y,
width: aWidth,
height: aHeigth,
radius: 10,
fill: appColor,
fillOpacity: model.highlight ? 0.3 : 0.05,
stroke: appColor
}
});
group.addShape("html", {
attrs: {
width: aWidth,
height: aHeigth,
color: appColor,
padding: "10px",
boxShadow: model.highlight ? `0 0 12px 0 ${appColor}` : "",
html: this.getHtml(cfg)
}
});
return shape;
},
getHtml(cfg) {
const model = cfg.model;
let icon = _this.getIconByType(model.type);
let color = _this.getColor(model.status);
let fontSize = model.fontSize || 12;
const dom = G6.Util.createDOM(
`<div class="draw-graph-app">
<svg class="draw-graph-app-icon" aria-hidden="true">
<use xlink:href="#${icon}" fill="${color}"></use>
</svg>
<div class="draw-graph-app-text" style="font-size:${fontSize}px">
${model.text}
</div>
</div>`
);
return dom;
},
afterDraw(cfg, group, keyShape) {},
getAnchorPoints() {
return [
[0, 0.25],
[0, 0.5],
[0, 0.75],
[1, 0.25],
[1, 0.5],
[1, 0.75],
[0.25, 0],
[0.5, 0],
[0.75, 0],
[0.25, 1],
[0.5, 1],
[0.75, 1]
];
}
});
}
..........
/* 右键菜单处理 */
this.g6Obj.on("contextmenu", function(ev) {
let type = ev.itemType;
if (type === undefined || type === "node") {
let appMenuRef = _this.$refs.appMenu;
if (type === undefined) {
appMenuRef = _this.$refs.graphMenu;
}
let appMenuDom = appMenuRef.$el;
let domEvent = ev.domEvent;
appMenuDom.children[0].style.left = domEvent.x + "px";
appMenuDom.children[0].style.top = domEvent.y + "px";
if (type === undefined) {
_this.graphMenuShow = true;
} else {
_this.appSelected = ev.item;
_this.appMenuShow = true;
}
}
});
刚好我研究出来了,我的做法是先画canvas节点,然后再画html节点,完美实现各种扩展要求,还有菜单那个得监听当前鼠标的坐标。给你代码片段你自己发挥你的想象吧。。。。
真心期待G6的开发人员能写出一些复杂的DEMO,或者是完善下api。。。这些东西我各种控制台里面打出来研究的。。。不过还好,不是太难。
PS:我用的是VUE+element-ui。
效果图如下:

@zx8887 自定义节点里的图片能不能跟随缩放?
@liekkas 可以的。我现在能无限放大和缩小。而且自定义变形图片也会跟着放大缩小的
@zx8887 选中节点缩放是可以的,但用鼠标滚轮的方式不能缩放。
其实,html 也是支持矩阵变换的,只是当初各种原因没做。 2.0 里已经实现了。 图编辑器是巨复杂的场景,要实现好的交互,打磨一点点细节就会耗费大量的精力。我们目前精力,只能沉淀自己平时业务中做过的场景,把比较有价值的个别场景沉淀下来提供给大家。
@liekkas 我的是可以的哟,我图片是根据外层div比例缩小放大的,外层div又是通过draw来动态变换大小的。

上动图给你看。代码就是上面的代码
@TomHuangCN html我知道是可以缩放的,之所以我在html之前又加了个canvas节点。是为了在minimap插件里面可以显示。。顺道问一问,minimap有什么方法能实现显示edge。。。。thx
model.fontSize,这个fontSize是自定义的吧,怎么实现动态改变的@zx8887
@JacobYChan 你可以理解为model是你自定义对象,你在update节点的时候,修改里面的fontSize就OK了。。我的这个代码字体缩放没有改变大小的,只是能自定义大小。因为如果要根据缩放来调整字体大小,算法有点麻烦,目前我做的是固定文字显示长度,超出部分...

你可以参考下面的代码修改字体大小。我是做测试随机大小的
let nodes = _this.g6Obj.getNodes();
if (nodes) {
nodes.forEach(node => {
let model = node.getModel();
let ran = parseInt(4 * Math.random());
let ranStatus = Object.keys(_this.colors)[ran];
model["status"] = ranStatus;
model["fontSize"] = ran + 12;
_this.g6Obj.update(model.id, model);
});
}
兄弟系统做的这么漂亮,要不投个简历吧。 @zx8887 https://github.com/antvis/g6/issues/208
@TomHuangCN 哥。我是被迫学习前端的。之前一直做java后台。。。目前还在学习前端各种框架和技术,估计达不到你们的要求。。。。
可以转啊,基础好就行,前端欢乐多 :-) @zx8887
@TomHuangCN 谢兄弟赏识。。。我个人觉得以目前的水平也只能应聘demo编写师,有没有这个职位嘛,哈哈哈
我以为是自动缩放字体的,你那个节点里如果刚好是个svg的图片,那缩放没问题,关键很多场景是节点里不是图片是各种文字,就像我上面放的效果图一样,这种情况下缩放就会有问题,对文字影响比较大,我在想能不能根据缩放调整字体大小的算法,这样的场景比较多一些@zx887
@JacobYChan 我之前尝试过字体缩放,但是效果不是太好,还有一种方式我觉得应该能行,我没尝试,就是动态监听鼠标滚轮事件
graph.on('mousewheel', function(ev){}); // 鼠标滚轮事件
然后动态设置html节点的transform:scale()缩放属性。。
我觉得应该行。但是我这个场景不适合,因为有minimap需要展示canvas节点,transform:scale()的缩放比例估计很难和canvas的缩放比例匹配。
@zx8887 思路不错,通过监听滚轮事件批量更新net.nodes.model,node在draw方法中拿到scale后设置transform即可。
大家还是喜欢用 dom,但 dom 还是或多或少会有些问题。
G6 2.0 已经对 dom 节点做了很多优化,但有些地方处理的还不够完美。所以还没发布到文档里。
等晚些时候,处理的完美些,争取在 G6 2.1 把 dom 节点发布出来
DOM落地这个事儿在G6 2.1里有了吗?
兄弟,还是用canvas话吧,字也是画出来的,无线缩放,要交互画个html里面包含svg图标,记录好id,在afterDraw里面document.getElementById绑定事件吧,我就这么做的。
兄弟,还是用canvas话吧,字也是画出来的,无线缩放,要交互画个html里面包含svg图标,记录好id,在afterDraw里面document.getElementById绑定事件吧,我就这么做的。
估计也只能这样了,不知道为什么我在G6 Editor里设定的renderer属性死活不生效……大哥可以写G6 Editor的文档了,感觉你用的已经比开发的人强了👍
兄弟,还是用canvas话吧,字也是画出来的,无线缩放,要交互画个html里面包含svg图标,记录好id,在afterDraw里面document.getElementById绑定事件吧,我就这么做的。
估计也只能这样了,不知道为什么我在G6 Editor里设定的renderer属性死活不生效……大哥可以写G6 Editor的文档了,感觉你用的已经比开发的人强了👍
我现在只用1.X。。。2.X没用。本来想用editor的。但是闭源+商业。。就只能老老实实1.X自己写一个editor了
上动图给你看。代码就是上面的代码
你好,好奇一个与该issue无关的问题。
请问你这个编辑器是如何实现的,看起来功能很强大!
上动图给你看。代码就是上面的代码你好,好奇一个与该issue无关的问题。
请问你这个编辑器是如何实现的,看起来功能很强大!
自己手动实现的。。vue Elementui
Most helpful comment
效果图如下:
