text: 
  /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
  * regarding copyright ownership.  The ASF licenses this file
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
  *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  * KIND, either express or implied.  See the License for the
  * specific language governing permissions and limitations
  * under the License.
  */
  
  var graphic = require("../../util/graphic");
  
  var echarts = require("../../echarts");
  
  var zrUtil = require("zrender/lib/core/util");
  
  /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
  * regarding copyright ownership.  The ASF licenses this file
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
  *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  * KIND, either express or implied.  See the License for the
  * specific language governing permissions and limitations
  * under the License.
  */
  
  /**
   * @file  The file used to draw sankey view
   * @author  Deqing Li(annong035@gmail.com)
   */
  var nodeOpacityPath = ['itemStyle', 'opacity'];
  var lineOpacityPath = ['lineStyle', 'opacity'];
  
  function getItemOpacity(item, opacityPath) {
    return item.getVisual('opacity') || item.getModel().get(opacityPath);
  }
  
  function fadeOutItem(item, opacityPath, opacityRatio) {
    var el = item.getGraphicEl();
    var opacity = getItemOpacity(item, opacityPath);
  
    if (opacityRatio != null) {
      opacity == null && (opacity = 1);
      opacity *= opacityRatio;
    }
  
    el.downplay && el.downplay();
    el.traverse(function (child) {
      if (child.type !== 'group') {
        child.setStyle('opacity', opacity);
      }
    });
  }
  
  function fadeInItem(item, opacityPath) {
    var opacity = getItemOpacity(item, opacityPath);
    var el = item.getGraphicEl();
    el.highlight && el.highlight();
    el.traverse(function (child) {
      if (child.type !== 'group') {
        child.setStyle('opacity', opacity);
      }
    });
  }
  
  var SankeyShape = graphic.extendShape({
    shape: {
      x1: 0,
      y1: 0,
      x2: 0,
      y2: 0,
      cpx1: 0,
      cpy1: 0,
      cpx2: 0,
      cpy2: 0,
      extent: 0,
      orient: ''
    },
    buildPath: function (ctx, shape) {
      var extent = shape.extent;
      var orient = shape.orient;
  
      if (orient === 'vertical') {
        ctx.moveTo(shape.x1, shape.y1);
        ctx.bezierCurveTo(shape.cpx1, shape.cpy1, shape.cpx2, shape.cpy2, shape.x2, shape.y2);
        ctx.lineTo(shape.x2 + extent, shape.y2);
        ctx.bezierCurveTo(shape.cpx2 + extent, shape.cpy2, shape.cpx1 + extent, shape.cpy1, shape.x1 + extent, shape.y1);
      } else {
        ctx.moveTo(shape.x1, shape.y1);
        ctx.bezierCurveTo(shape.cpx1, shape.cpy1, shape.cpx2, shape.cpy2, shape.x2, shape.y2);
        ctx.lineTo(shape.x2, shape.y2 + extent);
        ctx.bezierCurveTo(shape.cpx2, shape.cpy2 + extent, shape.cpx1, shape.cpy1 + extent, shape.x1, shape.y1 + extent);
      }
  
      ctx.closePath();
    }
  });
  
  var _default = echarts.extendChartView({
    type: 'sankey',
  
    /**
     * @private
     * @type {module:echarts/chart/sankey/SankeySeries}
     */
    _model: null,
  
    /**
     * @private
     * @type {boolean}
     */
    _focusAdjacencyDisabled: false,
    render: function (seriesModel, ecModel, api) {
      var sankeyView = this;
      var graph = seriesModel.getGraph();
      var group = this.group;
      var layoutInfo = seriesModel.layoutInfo; // view width
  
      var width = layoutInfo.width; // view height
  
      var height = layoutInfo.height;
      var nodeData = seriesModel.getData();
      var edgeData = seriesModel.getData('edge');
      var orient = seriesModel.get('orient');
      this._model = seriesModel;
      group.removeAll();
      group.attr('position', [layoutInfo.x, layoutInfo.y]); // generate a bezire Curve for each edge
  
      graph.eachEdge(function (edge) {
        var curve = new SankeyShape();
        curve.dataIndex = edge.dataIndex;
        curve.seriesIndex = seriesModel.seriesIndex;
        curve.dataType = 'edge';
        var lineStyleModel = edge.getModel('lineStyle');
        var curvature = lineStyleModel.get('curveness');
        var n1Layout = edge.node1.getLayout();
        var node1Model = edge.node1.getModel();
        var dragX1 = node1Model.get('localX');
        var dragY1 = node1Model.get('localY');
        var n2Layout = edge.node2.getLayout();
        var node2Model = edge.node2.getModel();
        var dragX2 = node2Model.get('localX');
        var dragY2 = node2Model.get('localY');
        var edgeLayout = edge.getLayout();
        var x1;
        var y1;
        var x2;
        var y2;
        var cpx1;
        var cpy1;
        var cpx2;
        var cpy2;
        curve.shape.extent = Math.max(1, edgeLayout.dy);
        curve.shape.orient = orient;
  
        if (orient === 'vertical') {
          x1 = (dragX1 != null ? dragX1 * width : n1Layout.x) + edgeLayout.sy;
          y1 = (dragY1 != null ? dragY1 * height : n1Layout.y) + n1Layout.dy;
          x2 = (dragX2 != null ? dragX2 * width : n2Layout.x) + edgeLayout.ty;
          y2 = dragY2 != null ? dragY2 * height : n2Layout.y;
          cpx1 = x1;
          cpy1 = y1 * (1 - curvature) + y2 * curvature;
          cpx2 = x2;
          cpy2 = y1 * curvature + y2 * (1 - curvature);
        } else {
          x1 = (dragX1 != null ? dragX1 * width : n1Layout.x) + n1Layout.dx;
          y1 = (dragY1 != null ? dragY1 * height : n1Layout.y) + edgeLayout.sy;
          x2 = dragX2 != null ? dragX2 * width : n2Layout.x;
          y2 = (dragY2 != null ? dragY2 * height : n2Layout.y) + edgeLayout.ty;
          cpx1 = x1 * (1 - curvature) + x2 * curvature;
          cpy1 = y1;
          cpx2 = x1 * curvature + x2 * (1 - curvature);
          cpy2 = y2;
        }
  
        curve.setShape({
          x1: x1,
          y1: y1,
          x2: x2,
          y2: y2,
          cpx1: cpx1,
          cpy1: cpy1,
          cpx2: cpx2,
          cpy2: cpy2
        });
        curve.setStyle(lineStyleModel.getItemStyle()); // Special color, use source node color or target node color
  
        switch (curve.style.fill) {
          case 'source':
            curve.style.fill = edge.node1.getVisual('color');
            break;
  
          case 'target':
            curve.style.fill = edge.node2.getVisual('color');
            break;
        }
  
        graphic.setHoverStyle(curve, edge.getModel('emphasis.lineStyle').getItemStyle());
        group.add(curve);
        edgeData.setItemGraphicEl(edge.dataIndex, curve);
      }); // Generate a rect for each node
  
      graph.eachNode(function (node) {
        var layout = node.getLayout();
        var itemModel = node.getModel();
        var dragX = itemModel.get('localX');
        var dragY = itemModel.get('localY');
        var labelModel = itemModel.getModel('label');
        var labelHoverModel = itemModel.getModel('emphasis.label');
        var rect = new graphic.Rect({
          shape: {
            x: dragX != null ? dragX * width : layout.x,
            y: dragY != null ? dragY * height : layout.y,
            width: layout.dx,
            height: layout.dy
          },
          style: itemModel.getModel('itemStyle').getItemStyle()
        });
        var hoverStyle = node.getModel('emphasis.itemStyle').getItemStyle();
        graphic.setLabelStyle(rect.style, hoverStyle, labelModel, labelHoverModel, {
          labelFetcher: seriesModel,
          labelDataIndex: node.dataIndex,
          defaultText: node.id,
          isRectText: true
        });
        rect.setStyle('fill', node.getVisual('color'));
        graphic.setHoverStyle(rect, hoverStyle);
        group.add(rect);
        nodeData.setItemGraphicEl(node.dataIndex, rect);
        rect.dataType = 'node';
      });
      nodeData.eachItemGraphicEl(function (el, dataIndex) {
        var itemModel = nodeData.getItemModel(dataIndex);
  
        if (itemModel.get('draggable')) {
          el.drift = function (dx, dy) {
            sankeyView._focusAdjacencyDisabled = true;
            this.shape.x += dx;
            this.shape.y += dy;
            this.dirty();
            api.dispatchAction({
              type: 'dragNode',
              seriesId: seriesModel.id,
              dataIndex: nodeData.getRawIndex(dataIndex),
              localX: this.shape.x / width,
              localY: this.shape.y / height
            });
          };
  
          el.ondragend = function () {
            sankeyView._focusAdjacencyDisabled = false;
          };
  
          el.draggable = true;
          el.cursor = 'move';
        }
  
        if (itemModel.get('focusNodeAdjacency')) {
          el.off('mouseover').on('mouseover', function () {
            if (!sankeyView._focusAdjacencyDisabled) {
              api.dispatchAction({
                type: 'focusNodeAdjacency',
                seriesId: seriesModel.id,
                dataIndex: el.dataIndex
              });
            }
          });
          el.off('mouseout').on('mouseout', function () {
            if (!sankeyView._focusAdjacencyDisabled) {
              api.dispatchAction({
                type: 'unfocusNodeAdjacency',
                seriesId: seriesModel.id
              });
            }
          });
        }
      });
      edgeData.eachItemGraphicEl(function (el, dataIndex) {
        var edgeModel = edgeData.getItemModel(dataIndex);
  
        if (edgeModel.get('focusNodeAdjacency')) {
          el.off('mouseover').on('mouseover', function () {
            if (!sankeyView._focusAdjacencyDisabled) {
              api.dispatchAction({
                type: 'focusNodeAdjacency',
                seriesId: seriesModel.id,
                edgeDataIndex: el.dataIndex
              });
            }
          });
          el.off('mouseout').on('mouseout', function () {
            if (!sankeyView._focusAdjacencyDisabled) {
              api.dispatchAction({
                type: 'unfocusNodeAdjacency',
                seriesId: seriesModel.id
              });
            }
          });
        }
      });
  
      if (!this._data && seriesModel.get('animation')) {
        group.setClipPath(createGridClipShape(group.getBoundingRect(), seriesModel, function () {
          group.removeClipPath();
        }));
      }
  
      this._data = seriesModel.getData();
    },
    dispose: function () {},
    focusNodeAdjacency: function (seriesModel, ecModel, api, payload) {
      var data = this._model.getData();
  
      var graph = data.graph;
      var dataIndex = payload.dataIndex;
      var itemModel = data.getItemModel(dataIndex);
      var edgeDataIndex = payload.edgeDataIndex;
  
      if (dataIndex == null && edgeDataIndex == null) {
        return;
      }
  
      var node = graph.getNodeByIndex(dataIndex);
      var edge = graph.getEdgeByIndex(edgeDataIndex);
      graph.eachNode(function (node) {
        fadeOutItem(node, nodeOpacityPath, 0.1);
      });
      graph.eachEdge(function (edge) {
        fadeOutItem(edge, lineOpacityPath, 0.1);
      });
  
      if (node) {
        fadeInItem(node, nodeOpacityPath);
        var focusNodeAdj = itemModel.get('focusNodeAdjacency');
  
        if (focusNodeAdj === 'outEdges') {
          zrUtil.each(node.outEdges, function (edge) {
            if (edge.dataIndex < 0) {
              return;
            }
  
            fadeInItem(edge, lineOpacityPath);
            fadeInItem(edge.node2, nodeOpacityPath);
          });
        } else if (focusNodeAdj === 'inEdges') {
          zrUtil.each(node.inEdges, function (edge) {
            if (edge.dataIndex < 0) {
              return;
            }
  
            fadeInItem(edge, lineOpacityPath);
            fadeInItem(edge.node1, nodeOpacityPath);
          });
        } else if (focusNodeAdj === 'allEdges') {
          zrUtil.each(node.edges, function (edge) {
            if (edge.dataIndex < 0) {
              return;
            }
  
            fadeInItem(edge, lineOpacityPath);
            fadeInItem(edge.node1, nodeOpacityPath);
            fadeInItem(edge.node2, nodeOpacityPath);
          });
        }
      }
  
      if (edge) {
        fadeInItem(edge, lineOpacityPath);
        fadeInItem(edge.node1, nodeOpacityPath);
        fadeInItem(edge.node2, nodeOpacityPath);
      }
    },
    unfocusNodeAdjacency: function (seriesModel, ecModel, api, payload) {
      var graph = this._model.getGraph();
  
      graph.eachNode(function (node) {
        fadeOutItem(node, nodeOpacityPath);
      });
      graph.eachEdge(function (edge) {
        fadeOutItem(edge, lineOpacityPath);
      });
    }
  }); // Add animation to the view
  
  
  function createGridClipShape(rect, seriesModel, cb) {
    var rectEl = new graphic.Rect({
      shape: {
        x: rect.x - 10,
        y: rect.y - 10,
        width: 0,
        height: rect.height + 20
      }
    });
    graphic.initProps(rectEl, {
      shape: {
        width: rect.width + 20,
        height: rect.height + 20
      }
    }, seriesModel, cb);
    return rectEl;
  }
  
  module.exports = _default;