网站导读怎么做,关键词seo优化案例,亚瑟中文 在线,做易购网站写在前面
在一些管理系统中#xff0c;会对组织架构、级联数据等做一些管理#xff0c;你会怎么实现呢#xff1f;在经过调研很多插件之后决定使用 Antv G6 实现#xff0c;文档也比较清晰#xff0c;看看怎么实现吧#xff0c;先来看看效果图。点击在线体验 实现的功能…写在前面
在一些管理系统中会对组织架构、级联数据等做一些管理你会怎么实现呢在经过调研很多插件之后决定使用 Antv G6 实现文档也比较清晰看看怎么实现吧先来看看效果图。点击在线体验 实现的功能有
增加节点删除节点编辑节点展开收起
具体实现
先在项目中安装 antv g6
npm install --save antv/g6vue 文件创建容器渲染
渲染的容器
div idcontainer classone-tree/div渲染方法和初始化树图
import G6 from antv/g6const state reactive({treeData: {id: root,sname: root,name: uniqueId(),children: [],},graph: null,
})function renderMap(data: any[], graph: Graph): void {G6.registerNode(icon-node,{options: {size: [60, 20],stroke: #73D13D,fill: #fff},draw(cfg: any, group: any) {const styles (this as any).getShapeStyle(cfg)const { labelCfg {} } cfgconst w cfg.size[0]const h cfg.size[1]const keyShape group.addShape(rect, {attrs: {...styles,cursor: pointer,x: 0,y: 0,width: w, // 200,height: h, // 60fill: cfg.style.fill || #fff},name: node-rect,draggable: true})// 动态增加和删除元素group.addShape(text, {attrs: {x: 131,y: 20,r: 6,stroke: #707070,cursor: pointer,opacity: 1,fontFamily: iconfont,textAlign: center,textBaseline: middle,text: \ue658,fontSize: 16},name: add-item})// 删除icon,根元素不能删除if (cfg.id ! root) {group.addShape(text, {attrs: {x: 110,y: 20,r: 6,fontFamily: iconfont,textAlign: center,textBaseline: middle,text: \ue74b,fontSize: 14,stroke: #909399,cursor: pointer,opacity: 0},name: remove-item})}if (cfg.sname) {group.addShape(text, {attrs: {...labelCfg.style,text: fittingString(cfg.sname, 110, 12),textAlign: left,x: 10,y: 25}})}// 展开收起if (cfg.children cfg.children.length 0) {group.addShape(circle, {attrs: {width: 24,height: 24,x: 154,y: 20,r: 12,cursor: pointer,lineWidth: 1,fill: !cfg.collapsed ? #9e9e9e : #2196f3,opacity: 1,text: 1},name: collapse-icon})group.addShape(text, {attrs: {...labelCfg.style,text: cfg.children.length,textAlign: left,x: 150,y: 25,fill: #ffffff,fontWeight: 500,cursor: pointer},name: collapse-icon})}return keyShape},setState(name, value, item) {const group item?.getContainer()if (name collapsed) {const marker item?.get(group).find((ele: any) ele.get(name) collapse-icon)const icon value ? G6.Marker.expand : G6.Marker.collapsemarker.attr(symbol, icon)}if (name selected) {const nodeRect group?.find(function (e) {return e.get(name) node-rect})if (value) {nodeRect?.attr({stroke: #2196f3,lineWidth: 2})}}if (name hover) {const addMarker group?.find(function (e) {return e.get(name) add-item})const reduceMarker group?.find(function (e) {return e.get(name) remove-item})if (value) {addMarker?.attr({opacity: 1})reduceMarker?.attr({opacity: 1})}}},update: undefined},rect)graph.data(data)graph.render()mouseenterNode(graph)mouseLeaveNode(graph)collapseNode(graph)
}function initGraph(graphWrapId: string): Graph {const width (document.getElementById(graphWrapId) as HTMLElement).clientWidth || 1000const height (document.getElementById(graphWrapId) as HTMLElement).clientHeight || 1000const graph new G6.TreeGraph({container: graphWrapId,width,height,linkCenter: true,animate: false,fitView: false, // 自动调整节点位置和缩放使得节点适应画布大小modes: {default: [scroll-canvas],edit: [click-select]},defaultNode: {type: icon-node,size: [120, 40],style: defaultNodeStyle,labelCfg: defaultLabelCfg},defaultEdge: {type: cubic-vertical},comboStateStyles,layout: defaultLayout})return graph
}事件处理
/*** description:树型图的事件绑定*/// 展开收起子节点
function collapseNode(graph: Graph): void {// 展开和收起子节点graph.on(node:click, (e: any) {if (e.target.get(name) collapse-icon) {e.item.getModel().collapsed !e.item.getModel().collapsedgraph.setItemState(e.item, collapsed, e.item.getModel().collapsed)graph.layout()}})
}// 鼠标滑入
function mouseenterNode(graph: Graph): void {graph.on(node:mouseover, (evt: any) {const { item, target } evtif (item._cfg.id root) returnconst canHoverName [node-rect, remove-item]if (!canHoverName.includes(target.get(name))) return// 显示iconconst deleteItem item.get(group).find(function (el: any) {return el.cfg.name remove-item})deleteItem.attr(opacity, 1)if (item._cfg item._cfg.keyShape) {item._cfg.keyShape.attr(stroke, #2196f3)}graph.setItemState(item, active, true)})
}// 鼠标离开
function mouseLeaveNode(graph: Graph): void {graph.on(node:mouseout, (evt: any) {const { item, target } evtconst canHoverName [node-rect, remove-item]if (item._cfg.id root) returnif (!canHoverName.includes(target.get(name))) return// 隐藏iconconst deleteItem item.get(group).find(function (el: any) {return el.cfg.name remove-item})deleteItem.attr(opacity, 0)if (item._cfg item._cfg.keyShape) {item._cfg.keyShape.attr(stroke, #fff)}graph.setItemState(item, active, false)})
}/*** description 文本超长显示*/
const fittingString (str: string, maxWidth: number, fontSize: number): string {const ellipsis ...const ellipsisLength Util.getTextSize(ellipsis, fontSize)[0]let currentWidth 0let res strconst pattern new RegExp([\u4E00-\u9FA5])str.split().forEach((letter, i) {if (currentWidth maxWidth - ellipsisLength) returnif (pattern.test(letter)) {currentWidth fontSize} else {currentWidth Util.getLetterWidth(letter, fontSize)}if (currentWidth maxWidth - ellipsisLength) {res ${str.substr(0, i)}${ellipsis}}})return res
}节点的增加、删除、编辑时间
const addEvent (graph: any) {graph.on(node:click, (evt: any) {const { item, target } evtconst name target.get(name)// 增加元素const model item.getModel()if (name add-item) {state.editType add// 如果收起需要展开if (model.collapsed) model.collapsed false// 没有子级的时候设置空数组if (!model.children) model.children []const id uniqueId()model.children.push({id,name: 1,sname: ,parentId: model.id,})graph.updateChild(model, model.id)const curTarget graph.findDataById(id)const canvasXY graph.getCanvasByPoint(curTarget.x, curTarget.y)state.editOne curTargetstate.input curTarget.snamesetTimeout(() {state.showInput truenextTick(() {inputRref.value.focus()})}, 200)// 更改输入框的位置state.inputStyle {left: ${canvasXY.x}px,top: ${canvasXY.y}px,}}// 删除节点if (name remove-item) {graph.removeChild(model.id)// 查找当前的父id更新其子元素的长度graph.updateItem(model.parentId, {})}// 编辑if (name node-rect) {const curTarget graph.findDataById(item._cfg.id)const canvasXY graph.getCanvasByPoint(curTarget.x, curTarget.y)state.editOne evt.itemstate.input curTarget.snamestate.showInput truestate.editType editnextTick(() {inputRref.value.focus()})state.inputStyle {left: ${canvasXY.x}px,top: ${canvasXY.y}px,}}})// 画布滚动、拖动时不能编辑节点名称graph.on(dragstart, () {state.showInput false})graph.on(wheel, () {state.showInput false})
}dom 节点渲染后渲染树图
onMounted(() {nextTick(() {state.graph initGraph(container)state.graph.clear()addEvent(state.graph)renderMap(state.treeData, state.graph)})
})相关链接
源码链接Antv G6 官网参考文章