d3.js如何附加链接标签

时间:2018-07-27 09:06:57

标签: javascript d3.js hyperlink label

我正在使用d3.js尝试生成如图所示的图像。我想在图像下方附加链接标签。

如何绘制下面的图像?

https://i.stack.imgur.com/qdR5j.png

下面是我的HTML来源

<svg id="mysvg" width="800" height="800">
    <defs>
        <marker id="arrow" markerUnits="strokeWidth" markerWidth="10" markerHeight="10" viewBox="0 0 12 12" refX="8.5" refY="5.8" orient="auto">
            <path d="M2,2 L10,6 L2,10 L6,6 L2,2" style="fill: steelblue;"></path>
        </marker>
    </defs>
</svg>

下面是Javascript来源

var diameter = 900, radius = diameter / 2, innerRadius = radius - 150

var cluster = d3.cluster().size([360, innerRadius])

var line = d3.radialLine()
    .curve(d3.curveBundle.beta(0.35))
    .radius(function(d) { return d.y })
    .angle(function(d) { return d.x / 180 * Math.PI })

var svg = d3.select('#mysvg')
  .attr('marker-end', 'url(#arrow)')
  .attr('width', diameter)
  .attr('height', diameter)
  .append('g')
  .attr('transform', 'translate(' + radius + ',' + radius + ')')

var link = svg.append('g').selectAll('.link')
var node = svg.append('g').selectAll('.node')

d3.json("http://localhost:3000/flare").then(function(classes) {
    var root = packageHierarchy(classes)
    cluster(root)

    link = link
        .data(packageImports(root.leaves()))
        .enter()
        .append('path')
        .each(function(d) {
            d.source = d[0], d.target = d[d.length - 1]
        })
        .attr('class', 'link')
        .attr('d', line)

    node
        .data(root.leaves())
        .enter()
        .append('text')
        .attr('class', 'node')
        .attr('dy', '0.31em')
        .attr('transform', function(d) {
            return 'rotate(' + (d.x - 90) + ')translate(' + (d.y + 8) + ',0)' + (d.x < 180 ? '' : 'rotate(180)')
        })
        .attr('text-anchor', function(d) {
            return d.x < 180 ? 'start' : 'end'
        })
        .text(function(d) {
            return d.data.key
        })
        .style('font-weight', 'bold')
        .style('font-size', '16px')
        .on('mouseover', mouseovered)
        .on('mouseout', mouseouted)
        .on('click', function () {
            alert(1)
        })

  node.data(root.leaves())
    .enter()
    .append('text')
    .attr('class', 'node')
    .attr('dy', '0.31em')
    .attr('transform', function(d) {
      return 'rotate(' + (d.x - 93) + ')translate(' + (d.y + 8) + ',0)' + (d.x < 180 ? '' : 'rotate(180)')
    })
    .attr('text-anchor', function(d) {
      return d.x < 180 ? 'start' : 'end'
    })
    .text(function(d) {
      return '(' + d.data.totalCallCnt + ')'
    })
    .style('font-weight', 'bold')
    .style('font-size', '13px')
    .on('mouseover', mouseovered)
    .on('mouseout', mouseouted)
    .on('click', function () {
      alert(1)
    })
})

function mouseovered(d) {
  node.each(function(n) {
    n.target = n.source = false
  })

  link.classed('link--target', function(l) {
    if (l.target === d)
      return l.source.source = true
  })
  .classed('link--source', function(l) {
    if (l.source === d)
      return l.target.target = true
  })
  .filter(function(l) {
    return l.target === d || l.source === d
  })
  .raise()

  node.classed('node--target', function(n) {
    return n.target
  })
  .classed('node--source', function(n) {
    return n.source
  })
}

function mouseouted(d) {
  link
    .classed('link--target', false)
    .classed('link--source', false)

  node
    .classed('node--target', false)
    .classed('node--source', false)
}

function packageHierarchy(classes) {
  var map = { }

  function find(name, data) {
    var node = map[name], i
    if (!node) {
      node = map[name] = data || { name: name, children: [] }
      if (name.length) {
        node.parent = find(name.substring(0, i = name.lastIndexOf('.')))
        node.parent.children.push(node)
        node.key = name.substring(i + 1)
      }
    }
    return node
  }

  classes.forEach(function(d) {
    find(d.name || d.id, d)
  })

  return d3.hierarchy(map[''])
}

function packageImports(nodes) {
  var map = {},
      imports = []

  nodes.forEach(function(d) {
    map[d.data.name || d.data.id] = d
  })

  nodes.forEach(function(d) {
    if (d.data.to) {
      d.data.to.forEach(function(i) {
        imports.push(map[d.data.name || d.data.id].path(map[i.name || i.id]))
      })
    }
  })

  return imports
}

,数据模型格式如下:

[
    {
        "id": "INIT",
        "name": null,
        "totalCallCnt": 0,
        "toScenarios": [
            {
                "id": "SCNRF1P2P5NA11352363",
                "name": "주문시나리오",
                "cnt": 2
            },
            {
                "id": "SCNRF31MKPOSAF9F5200",
                "name": "123123",
                "cnt": 24
            },
            {
                "id": "SCNRF31MN1MO03A8A4EC",
                "name": "ddd",
                "cnt": 3
            },
            {
                "id": "SCNRF373OPWPB04A5E2B",
                "name": "종료시나리오",
                "cnt": 1
            },
            {
                "id": "OOS",
                "name": null,
                "cnt": 8
            }
        ]
    },
    {
        "id": "SCNRF1P2P5NA11352363",
        "name": "주문시나리오",
        "totalCallCnt": 3,
        "recursiveCnt": 1,
        "toScenarios": [
            {
                "id": "OOS",
                "name": null,
                "cnt": 2
            }
        ]
    },
    {
        "id": "SCNRF31MKPOSAF9F5200",
        "name": "123123",
        "totalCallCnt": 34,
        "recursiveCnt": 10,
        "toScenarios": []
    },
    {
        "id": "SCNRF31MN1MO03A8A4EC",
        "name": "ddd",
        "totalCallCnt": 3,
        "recursiveCnt": 0,
        "toScenarios": [
            {
                "id": "OOS",
                "name": null,
                "cnt": 1
            }
        ]
    },
    {
        "id": "SCNRF373OPWPB04A5E2B",
        "name": "종료시나리오",
        "totalCallCnt": 1,
        "recursiveCnt": 0,
        "toScenarios": [
            {
                "id": "OOS",
                "name": null,
                "cnt": 1
            }
        ]
    },
    {
        "id": "OOS",
        "name": null,
        "totalCallCnt": 12,
        "recursiveCnt": 0,
        "toScenarios": []
    }
]

标签必须使用 cnt 属性!

因此链接标签必须显示'1'或'2'或'0'...

0 个答案:

没有答案