摘要:的插件系統(tǒng)做的相當(dāng)完善可惜文檔沒(méi)有具體說(shuō)到這里整理一下的插件插件大致分為四種類型行為可以理解為事件處理的插件就是和的樣式同樣是插件插件的布局之類這部分涉及的算法比較多插件就是自定義工具函數(shù)將其內(nèi)置中這四種插件都有各自的寫法以及但是文檔中沒(méi)有
G6的插件系統(tǒng)做的相當(dāng)完善, 可惜文檔沒(méi)有具體說(shuō)到. 這里整理一下g6的插件.
插件大致分為四種類型:
behaviour 行為, 可以理解為事件處理
node, edge的插件, 就是node和edge的樣式, 同樣是插件
layout插件, node的布局之類, 這部分涉及的算法比較多
Util插件, 就是自定義工具函數(shù), 將其內(nèi)置G6.Util中
這四種插件都有各自的寫法以及api, 但是文檔中沒(méi)有提到, 這里簡(jiǎn)單介紹一下. 一下都以官方插件為例.
behaviour 行為寫完發(fā)現(xiàn)其實(shí)官方有這部分的文檔: https://www.yuque.com/antv/g6/custom-interaction
請(qǐng)看下面代碼, 這部分是注冊(cè)一個(gè)右鍵拖動(dòng)的行為:
// g6/plugins/behaviour.analysis/index.js function panCanvas(graph, button = "left", panBlank = false) { let lastPoint; if (button === "right") { graph.behaviourOn("contextmenu", ev => { ev.domEvent.preventDefault(); }); } graph.behaviourOn("mousedown", ev => { if (button === "left" && ev.domEvent.button === 0 || button === "right" && ev.domEvent.button === 2) { if (panBlank) { if (!ev.shape) { lastPoint = { x: ev.domX, y: ev.domY }; } } else { lastPoint = { x: ev.domX, y: ev.domY }; } } }); // 鼠標(biāo)右鍵拖拽畫布空白處平移畫布交互 G6.registerBehaviour("rightPanBlank", graph => { panCanvas(graph, "right", true); })
然后在實(shí)例化graph的時(shí)候在modes中引入:
new Graph({ modes: { default: ["panCanvas"] } })
其實(shí)到這里我們已經(jīng)知道了, 只要是在一些內(nèi)置事件中注冊(cè)一下自定義事件再引入我們就可以稱之為一個(gè)行為插件. 但是我們還需要再深入一點(diǎn), 看到底是不是這樣的.
// g6/src/mixin/mode.js behaviourOn(type, fn) { const eventCache = this._eventCache; if (!eventCache[type]) { eventCache[type] = []; } eventCache[type].push(fn); this.on(type, fn); },
照老虎畫貓我們最終可以實(shí)現(xiàn)一個(gè)自己的行為插件:
// 未經(jīng)過(guò)驗(yàn)證 function test(graph) { graph.behaviourOn("mousedown" () => alert(1) ) } // 鼠標(biāo)右鍵拖拽畫布空白處平移畫布交互 G6.registerBehaviour("test", graph => { test(graph); }) new Graph({ modes: { default: ["test"] } })node, edge的插件
關(guān)于node, edge的插件的插件其實(shí)官方文檔上面的自定義形狀和自定義邊.
// g6/plugins/edge.polyline/index.js G6.registerEdge("polyline", { offset: 10, getPath(item) { const points = item.getPoints(); const source = item.getSource(); const target = item.getTarget(); return this.getPathByPoints(points, source, target); }, getPathByPoints(points, source, target) { const polylinePoints = getPolylinePoints(points[0], points[points.length - 1], source, target, this.offset); // FIXME default return Util.pointsToPolygon(polylinePoints); } }); G6.registerEdge("polyline-round", { borderRadius: 9, getPathByPoints(points, source, target) { const polylinePoints = simplifyPolyline( getPolylinePoints(points[0], points[points.length - 1], source, target, this.offset) ); // FIXME default return getPathWithBorderRadiusByPolyline(polylinePoints, this.borderRadius); } }, "polyline");
這部分那么多代碼其實(shí)最重要的還是上面的部分, 注冊(cè)一個(gè)自定義邊, 直接引入就可以在shape中使用了, 具體就不展開(kāi)了.
自定義邊
自定義節(jié)點(diǎn)
layout在初始化的時(shí)候即可以在 layout 字段中初始化也可以在plugins中.
const graph = new G6.Graph({ container: "mountNode", layout: dagre }) /* ---- */ const graph = new G6.Graph({ container: "mountNode", plugins: [ dagre ] })
原因在于寫插件的時(shí)候同時(shí)也把布局注冊(cè)為一個(gè)插件了:
// g6/plugins/layout.dagre/index.js class Plugin { constructor(options) { this.options = options; } init() { const graph = this.graph; graph.on("beforeinit", () => { const layout = new Layout(this.options); graph.set("layout", layout); }); } } G6.Plugins["layout.dagre"] = Plugin;
通過(guò)查看源碼我們可以知道自定義布局的核心方法就是execute, 再具體一點(diǎn)就是我們需要在每個(gè)布局插件中都有execute方法:
// g6/plugins/layout.dagre/layout.js // 執(zhí)行布局 execute() { const nodes = this.nodes; const edges = this.edges; const nodeMap = {}; const g = new dagre.graphlib.Graph(); const useEdgeControlPoint = this.useEdgeControlPoint; g.setGraph({ rankdir: this.getValue("rankdir"), align: this.getValue("align"), nodesep: this.getValue("nodesep"), edgesep: this.getValue("edgesep"), ranksep: this.getValue("ranksep"), marginx: this.getValue("marginx"), marginy: this.getValue("marginy"), acyclicer: this.getValue("acyclicer"), ranker: this.getValue("ranker") }); g.setDefaultEdgeLabel(function() { return {}; }); nodes.forEach(node => { g.setNode(node.id, { width: node.width, height: node.height }); nodeMap[node.id] = node; }); edges.forEach(edge => { g.setEdge(edge.source, edge.target); }); dagre.layout(g); g.nodes().forEach(v => { const node = g.node(v); nodeMap[v].x = node.x; nodeMap[v].y = node.y; }); g.edges().forEach((e, i) => { const edge = g.edge(e); if (useEdgeControlPoint) { edges[i].controlPoints = edge.points.slice(1, edge.points.length - 1); } }); }
上面是官方插件有向圖的核心代碼, 用到了dagre算法, 再簡(jiǎn)化一點(diǎn)其實(shí)可以理解為就是利用某種算法確定節(jié)點(diǎn)和邊的位置.
最終執(zhí)行布局的地方:
// g6/src/controller/layout.js graph._executeLayout(processor, nodes, edges, groups)Util插件
這類插件相對(duì)簡(jiǎn)單許多, 就是將函數(shù)內(nèi)置到Util中. 最后直接在G6.Util中使用即可
比如一個(gè)生成模擬數(shù)據(jù)的:
// g6/plugins/util.randomData/index.js const G6 = require("@antv/g6"); const Util = G6.Util; const randomData = { // generate chain graph data createChainData(num) { const nodes = []; const edges = []; for (let index = 0; index < num; index++) { nodes.push({ id: index }); } nodes.forEach((node, index) => { const next = nodes[index + 1]; if (next) { edges.push({ source: node.id, target: next.id }); } }); return { nodes, edges }; }, // generate cyclic graph data createCyclicData(num) { const data = randomData.createChainData(num); const { nodes, edges } = data; const l = nodes.length; edges.push({ source: data.nodes[l - 1].id, target: nodes[0].id }); return data; }, // generate num * num nodes without edges createNodesData(num) { const nodes = []; for (let index = 0; index < num * num; index++) { nodes.push({ id: index }); } return { nodes }; } }; Util.mix(Util, randomData);
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/99451.html
摘要:從年月,立項(xiàng)至今,已經(jīng)過(guò)去了年半的時(shí)間。期間獲得過(guò)贊譽(yù),也有吐槽,取得一定成就,也暴露過(guò)不少問(wèn)題。這次,我們很高興的告訴大家,今天除了開(kāi)源,還會(huì)開(kāi)放取得了階段性成果的詳見(jiàn)鏈接。與產(chǎn)品深度融合為了避免和成為工程師閉門造車的產(chǎn)物。 showImg(https://segmentfault.com/img/remote/1460000015199265?w=1500&h=756); G6 是...
摘要:準(zhǔn)備好數(shù)據(jù)節(jié)點(diǎn)節(jié)點(diǎn)節(jié)點(diǎn)坐標(biāo)節(jié)點(diǎn)坐標(biāo)邊節(jié)點(diǎn),從哪里出發(fā)節(jié)點(diǎn),到哪里結(jié)束初始化對(duì)象容器渲染位置,表示渲染到圖表的中間位置畫布高渲染數(shù)據(jù)這是渲染出來(lái)的效果。鏈接線會(huì)以元素為基準(zhǔn)。繪制元素時(shí),需要在初始化對(duì)象的時(shí)候,指定。 hello world // 1. 準(zhǔn)備好數(shù)據(jù) // node(節(jié)點(diǎn)) let nodes = [ { id: 1, // 節(jié)點(diǎn) id ...
摘要:騰訊云輕量應(yīng)用服務(wù)器免費(fèi)升級(jí)配置活動(dòng)開(kāi)始中騰訊云的活動(dòng)真的越來(lái)越良心了,前幾天剛剛出了一個(gè)免費(fèi)領(lǐng)取一年的核輕量應(yīng)用服務(wù)器活動(dòng)。騰訊云輕量應(yīng)用服務(wù)器免費(fèi)升級(jí)配置活動(dòng)開(kāi)始中!騰訊云的活動(dòng)真的越來(lái)越良心了,前幾天剛剛出了一個(gè)免費(fèi)領(lǐng)取一年的2核4G輕量應(yīng)用服務(wù)器活動(dòng)。今天,騰訊云又出了一個(gè)輕量應(yīng)用云服務(wù)器升級(jí)配置的活動(dòng),通過(guò)邀請(qǐng)五個(gè)好友進(jìn)行助力,可以將1核2G6M免費(fèi)升配2核4G6M,好友只需要點(diǎn)擊...
摘要:內(nèi)存硬盤帶寬月流量?jī)r(jià)格購(gòu)買核元年鏈接核元年鏈接核元年鏈接核元年鏈接活動(dòng)內(nèi)容活動(dòng)時(shí)間年月日年月日活動(dòng)對(duì)象騰訊云官網(wǎng)已注冊(cè)且完成實(shí)名認(rèn)證的國(guó)內(nèi)站用戶均可參與協(xié)作者與子用戶賬號(hào)除外發(fā)起助力購(gòu)買后,別忘記來(lái)這里發(fā)起你的助力活動(dòng)。騰訊云輕量應(yīng)用服務(wù)器周年慶免費(fèi)升配活動(dòng)開(kāi)始,也就是周年感恩回饋活動(dòng),加量不加價(jià)再返場(chǎng)!1核2G6M免費(fèi)升配2核4G6M,如何玩呢? 只要你購(gòu)買了秒殺活動(dòng)中的1核2G6M...
閱讀 917·2021-09-29 09:35
閱讀 1261·2021-09-28 09:36
閱讀 1531·2021-09-24 10:38
閱讀 1079·2021-09-10 11:18
閱讀 640·2019-08-30 15:54
閱讀 2508·2019-08-30 13:22
閱讀 1973·2019-08-30 11:14
閱讀 708·2019-08-29 12:35