vue d3 force cytoscape

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: {
            width: 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 {
  width: 90vw;
  height: 90vh;
}

h1 {
  opacity: 0.5;
  font-size: 1em;
}

</style>

记录进步。

posted @ 2021-06-30 13:13  玛卡巴鉲  阅读(303)  评论(0编辑  收藏  举报