src/sankeyCircular.js
function selectCircularLinkTypes (graph, id) {
    var numberOfTops = 0
    var numberOfBottoms = 0
    graph.links.forEach(function (link) {
      if (link.circular) {
        // if either souce or target has type already use that
        if (link.source.circularLinkType || link.target.circularLinkType) {
          // default to source type if available
          link.circularLinkType = link.source.circularLinkType
            ? link.source.circularLinkType
            : link.target.circularLinkType
        } else {
          link.circularLinkType = numberOfTops < numberOfBottoms
            ? 'top'
            : 'bottom'
        }

        if (link.circularLinkType == 'top') {
          numberOfTops = numberOfTops + 1
        } else {
          numberOfBottoms = numberOfBottoms + 1
        }

        graph.nodes.forEach(function (node) {
          if (getNodeID(node, id) == getNodeID(link.source, id) || getNodeID(node, id) == getNodeID(link.target, id)) {
            node.circularLinkType = link.circularLinkType
          }
        })
      }
    })

    //correct self-linking links to be same direction as node
    graph.links.forEach(function (link) {
      if (link.circular) {
        //if both source and target node are same type, then link should have same type
        if (link.source.circularLinkType == link.target.circularLinkType) {
          link.circularLinkType = link.source.circularLinkType
        }
        //if link is selflinking, then link should have same type as node
        if (selfLinking(link, id)) {
          link.circularLinkType = link.source.circularLinkType
        }
      }
    })

  }
function selectCircularLinkTypes (graph, id) {
    var numberOfTops = 0
    var numberOfBottoms = 0
    graph.links.forEach(function (link) {
      if (link.circular) {
        // if either souce or target has type already use that
        if (link.source.circularLinkType || link.target.circularLinkType) {
          // default to source type if available
          link.circularLinkType = link.source.circularLinkType
            ? link.source.circularLinkType
            : link.target.circularLinkType
        } else {
          link.circularLinkType = numberOfTops < numberOfBottoms
            ? 'top'
            : 'bottom'
        }

        if (link.circularLinkType == 'top') {
          numberOfTops = numberOfTops + 1
        } else {
          numberOfBottoms = numberOfBottoms + 1
        }

        graph.nodes.forEach(function (node) {
          if (getNodeID(node, id) == getNodeID(link.source, id) || getNodeID(node, id) == getNodeID(link.target, id)) {
            node.circularLinkType = link.circularLinkType
          }
        })
      }
    })

    //correct self-linking links to be same direction as node
    graph.links.forEach(function (link) {
      if (link.circular) {
        //if both source and target node are same type, then link should have same type
        if (link.source.circularLinkType == link.target.circularLinkType) {
          link.circularLinkType = link.source.circularLinkType
        }
        //if link is selflinking, then link should have same type as node
        if (selfLinking(link, id)) {
          link.circularLinkType = link.source.circularLinkType
        }
      }
    })

  }
function selectCircularLinkTypes ( graph , id ) { var numberOfTops = 0 var numberOfBottoms = 0 graph . links . forEach ( function ( link ) { if ( link . circular ) { // if either souce or target has type already use that if ( link . source . circularLinkType || link . target . circularLinkType ) { // default to source type if available link . circularLinkType = link . source . circularLinkType ? link . source . circularLinkType : link . target . circularLinkType } else { link . circularLinkType = numberOfTops < numberOfBottoms ? 'top' : 'bottom' } if ( link . circularLinkType == 'top' ) { numberOfTops = numberOfTops + 1 } else { numberOfBottoms = numberOfBottoms + 1 } graph . nodes . forEach ( function ( node ) { if ( getNodeID ( node , id ) == getNodeID ( link . source , id ) || getNodeID ( node , id ) == getNodeID ( link . target , id ) ) { node . circularLinkType = link . circularLinkType } } ) } } ) //correct self-linking links to be same direction as node graph . links . forEach ( function ( link ) { if ( link . circular ) { //if both source and target node are same type, then link should have same type if ( link . source . circularLinkType == link . target . circularLinkType ) { link . circularLinkType = link . source . circularLinkType } //if link is selflinking, then link should have same type as node if ( selfLinking ( link , id ) ) { link . circularLinkType = link . source . circularLinkType } } } ) }
Assign a circular link type (top or bottom), based on: - if the source/target node already has circular links, then use the same type - if not, choose the type with fewer links
Assign a circular link type ( top or bottom ) based on : - if the source / target node already has circular links then use the same type - if not choose the type with fewer links