UNPKG

dagre-d3

Version:

A D3-based renderer for Dagre

120 lines (97 loc) 3.3 kB
"use strict"; var _ = require("./lodash"); var intersectNode = require("./intersect/intersect-node"); var util = require("./util"); var d3 = require("./d3"); module.exports = createEdgePaths; function createEdgePaths(selection, g, arrows) { var previousPaths = selection.selectAll("g.edgePath") .data(g.edges(), function(e) { return util.edgeToId(e); }) .classed("update", true); var newPaths = enter(previousPaths, g); exit(previousPaths, g); var svgPaths = previousPaths.merge !== undefined ? previousPaths.merge(newPaths) : previousPaths; util.applyTransition(svgPaths, g) .style("opacity", 1); // Save DOM element in the path group, and set ID and class svgPaths.each(function(e) { var domEdge = d3.select(this); var 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) { var edge = g.edge(e); edge.arrowheadId = _.uniqueId("arrowhead"); var domEdge = d3.select(this) .attr("marker-end", function() { return "url(" + makeFragmentRef(location.href, 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) { var edge = g.edge(e); var arrowhead = arrows[edge.arrowhead]; arrowhead(d3.select(this), edge.arrowheadId, edge, "arrowhead"); }); return svgPaths; } function makeFragmentRef(url, fragmentId) { var baseUrl = url.split("#")[0]; return baseUrl + "#" + fragmentId; } function calcPoints(g, e) { var edge = g.edge(e); var tail = g.node(e.v); var head = g.node(e.w); var 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) { var line = (d3.line || d3.svg.line)() .x(function(d) { return d.x; }) .y(function(d) { return d.y; }); (line.curve || line.interpolate)(edge.curve); return line(points); } function getCoords(elem) { var bbox = elem.getBBox(); var 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) { var svgPathsEnter = svgPaths.enter().append("g") .attr("class", "edgePath") .style("opacity", 0); svgPathsEnter.append("path") .attr("class", "path") .attr("d", function(e) { var edge = g.edge(e); var sourceElem = g.node(e.v).elem; var points = _.range(edge.points.length).map(function() { return getCoords(sourceElem); }); return createLine(edge, points); }); svgPathsEnter.append("defs"); return svgPathsEnter; } function exit(svgPaths, g) { var svgPathExit = svgPaths.exit(); util.applyTransition(svgPathExit, g) .style("opacity", 0) .remove(); }