1. d3 force
<template> <div :id="id"> <svg width="100vw" height="100vh" /> </div> </template> <script> /** * 力导向图 */ import * as d3 from 'd3' let gs = '' let forceSimulation = '' let links = '' let linksText = '' const nodes = [ { name: '湖南' }, { name: '毛' }, { name: '主席' }, { name: '湖南' }, { name: '毛' }, { name: '主席' }, { name: '湖南' }, { name: '毛' }, { name: '主席' } ] const edges = [ { source: 0, target: 1, relation: '籍贯', value: 1 }, { source: 0, target: 2, relation: '职责', value: 1 }, { source: 0, target: 3, relation: '职责', value: 1 }, { source: 0, target: 4, relation: '职责', value: 1 }, { source: 0, target: 5, relation: '职责', value: 1 }, { source: 0, target: 6, relation: '职责', value: 1 }, { source: 0, target: 7, relation: '职责', value: 1 }, { source: 0, target: 8, relation: '职责', value: 1 }, { source: 1, target: 2, relation: '职责', value: 1 }, { source: 2, target: 3, relation: '职责', value: 1 }, { source: 3, target: 4, relation: '职责', value: 1 }, { source: 4, target: 5, relation: '职责', value: 1 }, { source: 5, target: 6, relation: '职责', value: 1 }, { source: 6, target: 7, relation: '职责', value: 1 }, { source: 7, target: 8, relation: '职责', value: 1 }, { source: 8, target: 1, relation: '职责', value: 1 } ] export default { name: 'Scale', data() { return { id: '' } }, created() { this.id = this.uuid() }, mounted() { // 1.创建svg画布 const marge = { top: 160, bottom: 60, left: 160, right: 60 } const width = document.getElementById(this.id).clientWidth const height = document.getElementById(this.id).clientHeight const svg = d3 .select(this.$el) .select('svg') .attr('width', width) .attr('height', height) const g = svg .append('g') .attr( 'transform', 'translate(' + marge.top + ',' + marge.left + ')' ) // 2.设置一个color的颜色比例尺,为了让不同的扇形呈现不同的颜色 var colorScale = d3 .scaleOrdinal() .domain(d3.range(nodes.length)) .range(d3.schemeCategory10) // 3.新建一个力导向图 forceSimulation = d3 .forceSimulation() .force('link', d3.forceLink()) .force('charge', d3.forceManyBody()) .force('center', d3.forceCenter()) .force('collide', d3.forceCollide().radius(60).iterations(2)) // 4. 初始化力导向图 // 生成节点数据 forceSimulation.nodes(nodes).on('tick', this.ticked) // 生成边数据 forceSimulation .force('link') .links(edges) .distance(function(d) { // 每一边的长度 return d.value * 100 }) // 设置图形的中心位置 forceSimulation .force('center') .x(width / 4) .y(height / 4) // 5. 绘制边(有了节点和边的数据后) links = g .append('g') .selectAll('line') .data(edges) .enter() .append('line') .attr('stroke', function(d, i) { return colorScale(i) }) .attr('stroke-width', 1) linksText = g .append('g') .selectAll('text') .data(edges) .enter() .append('text') .text(function(d) { return d.relation }) // 6. 绘制节点, 先为节点和节点上的文字分组 gs = g .selectAll('.circleText') .data(nodes) .enter() .append('g') .attr('transform', function(d, i) { var cirX = d.x var cirY = d.y return 'translate(' + cirX + ',' + cirY + ')' }) .call( d3 .drag() .on('start', this.dragStart) .on('drag', this.drag) .on('end', this.dragEnd) ) // 绘制节点 gs.append('circle') .attr('r', 10) .attr('fill', function(d, i) { return colorScale(i) }) // 文字 gs.append('text') .attr('x', -10) .attr('y', -20) .attr('dy', 10) .text(function(d) { return d.name }) }, methods: { uuid() { function s4() { return Math.floor((1 + Math.random()) * 0x10000) .toString(16) .substring(1) } return ( s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4() ) }, ticked() { links .attr('x1', function(d) { return d.source.x }) .attr('y1', function(d) { return d.source.y }) .attr('x2', function(d) { return d.target.x }) .attr('y2', function(d) { return d.target.y }) linksText .attr('x', function(d) { return (d.source.x + d.target.x) / 2 }) .attr('y', function(d) { return (d.source.y + d.target.y) / 2 }) gs.attr('transform', d => { return 'translate(' + d.x + ',' + d.y + ')' }) }, dragStart(d) { d.fx = d.x d.fy = d.y }, dragEnd(d) { if (!d3.event.active) { forceSimulation.alphaTarget(0) } d.fx = null d.fy = null }, drag(d) { forceSimulation.alphaTarget(0.7).restart() d.fx = d3.event.x d.fy = d3.event.y } } } </script> <style lang='scss' scoped> </style>
2.cytoscape
<template> <div id="box"> <h1>demo</h1> <div id="cy" /> </div> </template> <script> import cytoscape from 'cytoscape' export default { name: 'Cytoscape', components: {}, data() { return { nodes: [ { data: { id: 'n0', label: '哈哈哈' }}, { data: { id: 'n1', label: '嘟嘟嘟' }}, { data: { id: 'n2', label: '嘿嘿嘿' }}, { data: { id: 'n3', label: '啦啦啦' }}, { data: { id: 'n4', label: '嘀嘀嘀' }}, { data: { id: 'n5', label: '噜噜噜' }} ], edges: [ { data: { source: 'n2', target: 'n1' }}, { data: { source: 'n2', target: 'n3' }}, { data: { source: 'n2', target: 'n0' }}, { data: { source: 'n1', target: 'n0' }}, { data: { source: 'n0', target: 'n1' }}, { data: { source: 'n4', target: 'n5' }}, { data: { source: 'n3', target: 'n4' }}, { data: { source: 'n5', target: 'n0' }}, { data: { source: 'n5', target: 'n1' }}, { data: { source: 'n5', target: 'n2' }}, { data: { source: 'n5', target: 'n3' }}, { data: { source: 'n4', target: 'n3' }} ] } }, mounted() { this.createCytoscape() }, methods: { createCytoscape() { cytoscape.warnings(false) cytoscape({ container: document.getElementById('cy'), boxSelectionEnabled: false, userZoomingEnabled: false, // 滚轮缩放 wheelSensitivity: 0.1, autounselectify: true, autoungrabify: false, autolock: false, layout: { name: 'circle' }, minZoom: 0.3, style: [{ selector: 'node', style: { 'content': 'data(label)', 'height': 100, 'width': 100, 'color': '#fff', 'pie-size': '100%', 'text-valign': 'center', 'text-halign': 'center', 'background-color': '#fd942a' } }, { selector: ':parent', css: { 'text-valign': 'top', 'text-halign': 'center' // 'text-halign': 'right', // 'text-rotation': '90deg', //文字旋转 } }, { selector: 'edge', style: { 3, label: 'data(label)', 'target-arrow-shape': 'triangle', // "target-arrow-fill": "hollow", //箭头填充 空心 'line-color': '#9dbaea', 'target-arrow-color': '#9dbaea', 'curve-style': 'bezier' } } ], elements: { // 节点数据 nodes: this.nodes, // edges: this.edges } }) } } } </script> <style lang="scss" scoped> #cy { 90vw; height: 90vh; } h1 { opacity: 0.5; font-size: 1em; } </style>
记录进步。