| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- import * as d3 from 'd3'
- import _ from 'lodash'
- import intersectNode from './intersect/intersect-node'
- import util from './util'
- function createEdgePaths (selection, g, arrows) {
- let svgPaths = selection.selectAll('g.edgePath')
- .data(g.edges(), function (e) { return util.edgeToId(e) })
- .classed('update', true)
- enter(svgPaths, g)
- exit(svgPaths, g)
- svgPaths = selection.selectAll('g.edgePath')
- util.applyTransition(svgPaths, g)
- .style('opacity', 1)
- // Save DOM element in the path group, and set ID and class
- svgPaths.each(function (e) {
- const domEdge = d3.select(this)
- const edge = g.edge(e)
- edge.elem = this
- if (edge.id) {
- domEdge.attr('id', edge.id)
- }
- util.applyClass(domEdge, edge['class'],
- (domEdge.classed('update') ? 'update ' : '') + 'edgePath')
- })
- svgPaths.selectAll('path.path')
- .each(function (e) {
- const edge = g.edge(e)
- edge.arrowheadId = _.uniqueId('arrowhead')
- const domEdge = d3.select(this)
- .attr('marker-end', function () {
- return 'url(#' + edge.arrowheadId + ')'
- })
- .style('fill', 'none')
- util.applyTransition(domEdge, g)
- .attr('d', function (e) { return calcPoints(g, e) })
- util.applyStyle(domEdge, edge.style)
- })
- svgPaths.selectAll('defs *').remove()
- svgPaths.selectAll('defs')
- .each(function (e) {
- const edge = g.edge(e)
- const arrowhead = arrows[edge.arrowhead]
- arrowhead(d3.select(this), edge.arrowheadId, edge, 'arrowhead')
- })
- return svgPaths
- }
- function calcPoints (g, e) {
- const edge = g.edge(e)
- const tail = g.node(e.v)
- const head = g.node(e.w)
- const points = edge.points.slice(1, edge.points.length - 1)
- points.unshift(intersectNode(tail, points[0]))
- points.push(intersectNode(head, points[points.length - 1]))
- return createLine(edge, points)
- }
- function createLine (edge, points) {
- const line = d3.line()
- .x(function (d) { return d.x })
- .y(function (d) { return d.y })
- line.curve(edge.curve)
- return line(points)
- }
- function getCoords (elem) {
- const bbox = elem.getBBox()
- const matrix = elem.ownerSVGElement.getScreenCTM()
- .inverse()
- .multiply(elem.getScreenCTM())
- .translate(bbox.width / 2, bbox.height / 2)
- return { x: matrix.e, y: matrix.f }
- }
- function enter (svgPaths, g) {
- const svgPathsEnter = svgPaths.enter()
- .append('g')
- .attr('class', 'edgePath')
- .style('opacity', 0)
- svgPathsEnter.append('path')
- .attr('class', 'path')
- .attr('d', function (e) {
- const edge = g.edge(e)
- const sourceElem = g.node(e.v).elem
- const points = _.range(edge.points.length).map(function () { return getCoords(sourceElem) })
- return createLine(edge, points)
- })
- svgPathsEnter.append('defs')
- }
- function exit (svgPaths, g) {
- const svgPathExit = svgPaths.exit()
- util.applyTransition(svgPathExit, g)
- .style('opacity', 0)
- .remove()
- util.applyTransition(svgPathExit.select('path.path'), g)
- .attr('d', function (e) {
- const source = g.node(e.v)
- if (source) {
- const points = _.range(this.getTotalLength()).map(function () { return source })
- return createLine({}, points)
- } else {
- return d3.select(this).attr('d')
- }
- })
- }
- export default createEdgePaths
|