whole_func_string: function(vertices) {
  
          var sourcePoint = g.point(this._sourcePoint);
          var targetPoint = g.point(this._targetPoint);
  
          // Move the source point by the width of the marker taking into account its scale around x-axis.
          // Note that scale is the only transform that makes sense to be set in `.marker-source` attributes object
          // as all other transforms (translate/rotate) will be replaced by the `translateAndAutoOrient()` function.
  
          if (this._V.markerSource) {
              this._markerSourceBbox = this._markerSourceBbox || this._V.markerSource.bbox(true);
              sourcePoint.move(
                  this._firstVertex || targetPoint,
                  this._markerSourceBbox.width * -this._V.markerSource.scale().sx
              );
          }
  
          if (this._V.markerTarget) {
              this._markerTargetBbox = this._markerTargetBbox || this._V.markerTarget.bbox(true);
              targetPoint.move(
                  this._lastVertex || sourcePoint,
                  this._markerTargetBbox.width * -this._V.markerTarget.scale().sx
              );
          }
  
          var d;
          if (this.model.get('smooth')) {
  
              if (vertices && vertices.length) {
                  d = g.bezier.curveThroughPoints([sourcePoint].concat(vertices || []).concat([targetPoint]));
              } else {
                  // if we have no vertices use a default cubic bezier curve, cubic bezier requires two control points.
                  // the two control points are both defined with X as mid way between the source and target points.
                  // sourceControlPoint Y is equal to sourcePoint Y and targetControlPointY being equal to targetPointY.
                  // handle situation were sourcePointX is greater or less then targetPointX.
                  var controlPointX = (sourcePoint.x < targetPoint.x) 
                      ? targetPoint.x - ((targetPoint.x - sourcePoint.x) / 2)
                      : sourcePoint.x - ((sourcePoint.x - targetPoint.x) / 2);
                      d = ['M', sourcePoint.x, sourcePoint.y, 'C', controlPointX, sourcePoint.y, controlPointX, targetPoint.y, targetPoint.x, targetPoint.y];
              }
              
          } else {
              
              // Construct the `d` attribute of the `<path>` element.
              d = ['M', sourcePoint.x, sourcePoint.y];
              _.each(vertices, function(vertex) {
  
                  d.push(vertex.x, vertex.y);
              });
              d.push(targetPoint.x, targetPoint.y);
          }
  
          return d.join(' ');
      }
func_code_string: function(vertices) {
  
          var sourcePoint = g.point(this._sourcePoint);
          var targetPoint = g.point(this._targetPoint);
  
          // Move the source point by the width of the marker taking into account its scale around x-axis.
          // Note that scale is the only transform that makes sense to be set in `.marker-source` attributes object
          // as all other transforms (translate/rotate) will be replaced by the `translateAndAutoOrient()` function.
  
          if (this._V.markerSource) {
              this._markerSourceBbox = this._markerSourceBbox || this._V.markerSource.bbox(true);
              sourcePoint.move(
                  this._firstVertex || targetPoint,
                  this._markerSourceBbox.width * -this._V.markerSource.scale().sx
              );
          }
  
          if (this._V.markerTarget) {
              this._markerTargetBbox = this._markerTargetBbox || this._V.markerTarget.bbox(true);
              targetPoint.move(
                  this._lastVertex || sourcePoint,
                  this._markerTargetBbox.width * -this._V.markerTarget.scale().sx
              );
          }
  
          var d;
          if (this.model.get('smooth')) {
  
              if (vertices && vertices.length) {
                  d = g.bezier.curveThroughPoints([sourcePoint].concat(vertices || []).concat([targetPoint]));
              } else {
                  // if we have no vertices use a default cubic bezier curve, cubic bezier requires two control points.
                  // the two control points are both defined with X as mid way between the source and target points.
                  // sourceControlPoint Y is equal to sourcePoint Y and targetControlPointY being equal to targetPointY.
                  // handle situation were sourcePointX is greater or less then targetPointX.
                  var controlPointX = (sourcePoint.x < targetPoint.x) 
                      ? targetPoint.x - ((targetPoint.x - sourcePoint.x) / 2)
                      : sourcePoint.x - ((sourcePoint.x - targetPoint.x) / 2);
                      d = ['M', sourcePoint.x, sourcePoint.y, 'C', controlPointX, sourcePoint.y, controlPointX, targetPoint.y, targetPoint.x, targetPoint.y];
              }
              
          } else {
              
              // Construct the `d` attribute of the `<path>` element.
              d = ['M', sourcePoint.x, sourcePoint.y];
              _.each(vertices, function(vertex) {
  
                  d.push(vertex.x, vertex.y);
              });
              d.push(targetPoint.x, targetPoint.y);
          }
  
          return d.join(' ');
      }
func_documentation_string: Return the `d` attribute value of the `<path>` element representing the link between `source` and `target`.