anchor.diff:    return {'x': cx + dx, 'y': cy + dy};
   }
   
  -sameSign(r1, r2) {
  +bool sameSign(num r1, num r2) {
     return r1 * r2 > 0;
   }
   
   // Add point to the found intersections, but check first that it is unique.
  -addPoint(x, y, intersections) {
  -  if (!intersections.some((elm) { return elm[0] == x && elm[1] == y; })) {
  -    intersections.push([x, y]);
  -  }
  -}
  -
  -intersectLine(x1, y1, x2, y2, x3, y3, x4, y4, intersections) {
  +void addPoint(num x, num y, List intersections) {
  +  if (!intersections.any((elm) { return elm[0] == x && elm[1] == y; })) {
  +    intersections.add([x, y]);
  +  }
  +}
  +
  +void intersectLine(num x1, num y1, num x2, num y2, num x3, num y3, num x4, num y4, List intersections) {
     // Algorithm from J. Avro, (ed.) Graphics Gems, No 2, Morgan Kaufmann, 1994, p7 and p473.
   
  -  var a1, a2, b1, b2, c1, c2;
  -  var r1, r2 , r3, r4;
  -  var denom, offset, num;
  -  var x, y;
  +//  var a1, a2, b1, b2, c1, c2;
  +//  var r1, r2 , r3, r4;
  +//  var denom, offset, num;
  +//  var x, y;
   
     // Compute a1, b1, c1, where line joining points 1 and 2 is F(x,y) = a1 x + b1 y + c1 = 0.
  -  a1 = y2 - y1;
  -  b1 = x1 - x2;
  -  c1 = (x2 * y1) - (x1 * y2);
  +  final a1 = y2 - y1;
  +  final b1 = x1 - x2;
  +  final c1 = (x2 * y1) - (x1 * y2);
   
     // Compute r3 and r4.
  -  r3 = ((a1 * x3) + (b1 * y3) + c1);
  -  r4 = ((a1 * x4) + (b1 * y4) + c1);
  +  final r3 = ((a1 * x3) + (b1 * y3) + c1);
  +  final r4 = ((a1 * x4) + (b1 * y4) + c1);
   
     // Check signs of r3 and r4. If both point 3 and point 4 lie on
     // same side of line 1, the line segments do not intersect.
  
positive.code:   }
  
    // Compute a2, b2, c2 where line joining points 3 and 4 is G(x,y) = a2 x + b2 y + c2 = 0
    a2 = y4 - y3;
    b2 = x3 - x4;
    c2 = (x4 * y3) - (x3 * y4);
  
    // Compute r1 and r2
    r1 = (a2 * x1) + (b2 * y1) + c2;
    r2 = (a2 * x2) + (b2 * y2) + c2;
  
    // Check signs of r1 and r2. If both point 1 and point 2 lie
    // on same side of second line segment, the line segments do
  
negative.code: 
      svgEdgePaths
        .selectAll('path')
        ..each((Element node, Object e, int i, int j) {
          applyStyle(g.edge(e).style, new d3.Selection.node(node));
        })
        ..attr('marker-end', createArrowhead);
  
      this.transition(svgEdgePaths.exit())
          ..style('opacity', 0)
          ..remove();
  
      return svgEdgePaths;
    }
  
    void positionNodes(BaseGraph g, d3.Selection svgNodes) {
      transform(Element node, Object u, int i, int j) {
        Map value = g.node(u);
        return 'translate(${value['x']},${value['y']})';
      }
  
      // For entering nodes, position immediately without transition
      svgNodes.filter('.enter').attr('transform', transform);
  
      this.transition(svgNodes)
          ..style('opacity', 1)
          ..attrFunc('transform', transform);
    }
  
    void positionEdgeLabels(BaseGraph g, d3.Selection svgEdgeLabels) {
      transform(Element node, Object e, int i, int j) {
        var value = g.edge(e);
        var point = findMidPoint(value.points);
        return 'translate(${point.x},${point.y})';
      }
  
      // For entering edge labels, position immediately without transition
  
      svgEdgeLabels.filter('.enter').attr('transform', transform);
      this.transition(svgEdgeLabels)
        ..style('opacity', 1)
        ..attrFunc('transform', transform);
    }
  
    void positionEdgePaths(BaseGraph g, d3.Selection svgEdgePaths, d3.Selection root) {
      final interpolate = this.edgeInterpolate,
          tension = this.edgeTension;
  
      calcPoints(Element node, Object e, int i, int j) {
        Map value = g.edge(e);
        Map source = g.node(g.incidentNodes(e)[0]);
        Map target = g.node(g.incidentNodes(e)[1]);
        List points = value['points'].toList();
  
        var p0 = points.length == 0 ? target : points[0];
        var p1 = points.length == 0 ? source : points[points.length - 1];
  
        points.insert(0, intersectNode(source, p0, root));
        points.add(intersectNode(target, p1, root));
  
        return (new d3.Line()
          ..x = (d) { return d.x; }
          ..y = (d) { return d.y; }
          ..interpolate = interpolate
          ..tension = tension)
          .line(points);
      }
  
      svgEdgePaths.filter('.enter').selectAll('path')
          .attrFunc('d', calcPoints);
  
      this.transition(svgEdgePaths.selectAll('path'))
          ..attr('d', calcPoints)
          ..style('opacity', 1);
    }
  
    // By default we do not use transitions
  