| define(function (require) { |
| |
| var graphic = require('../../util/graphic'); |
| var zrUtil = require('zrender/core/util'); |
| |
| var SankeyShape = graphic.extendShape({ |
| shape: { |
| x1: 0, y1: 0, |
| x2: 0, y2: 0, |
| cpx1: 0, cpy1: 0, |
| cpx2: 0, cpy2: 0, |
| |
| extent: 0 |
| }, |
| |
| buildPath: function (ctx, shape) { |
| var halfExtent = shape.extent / 2; |
| ctx.moveTo(shape.x1, shape.y1 - halfExtent); |
| ctx.bezierCurveTo( |
| shape.cpx1, shape.cpy1 - halfExtent, |
| shape.cpx2, shape.cpy2 - halfExtent, |
| shape.x2, shape.y2 - halfExtent |
| ); |
| ctx.lineTo(shape.x2, shape.y2 + halfExtent); |
| ctx.bezierCurveTo( |
| shape.cpx2, shape.cpy2 + halfExtent, |
| shape.cpx1, shape.cpy1 + halfExtent, |
| shape.x1, shape.y1 + halfExtent |
| ); |
| ctx.closePath(); |
| } |
| }); |
| |
| return require('../../echarts').extendChartView({ |
| |
| type: 'sankey', |
| |
| /** |
| * @private |
| * @type {module:echarts/chart/sankey/SankeySeries} |
| */ |
| _model: null, |
| |
| render: function(seriesModel, ecModel, api) { |
| var graph = seriesModel.getGraph(); |
| var group = this.group; |
| var layoutInfo = seriesModel.layoutInfo; |
| |
| this._model = seriesModel; |
| |
| group.removeAll(); |
| |
| group.position = [layoutInfo.x, layoutInfo.y]; |
| |
| // generate a rect for each node |
| graph.eachNode(function (node) { |
| var layout = node.getLayout(); |
| var itemModel = node.getModel(); |
| var labelModel = itemModel.getModel('label.normal'); |
| var textStyleModel = labelModel.getModel('textStyle'); |
| var labelHoverModel = itemModel.getModel('label.emphasis'); |
| var textStyleHoverModel = labelHoverModel.getModel('textStyle'); |
| |
| var rect = new graphic.Rect({ |
| shape: { |
| x: layout.x, |
| y: layout.y, |
| width: node.getLayout().dx, |
| height: node.getLayout().dy |
| }, |
| style: { |
| // Get formatted label in label.normal option. Use node id if it is not specified |
| text: labelModel.get('show') |
| ? seriesModel.getFormattedLabel(node.dataIndex, 'normal') || node.id |
| // Use empty string to hide the label |
| : '', |
| textFont: textStyleModel.getFont(), |
| textFill: textStyleModel.getTextColor(), |
| textPosition: labelModel.get('position') |
| } |
| }); |
| |
| rect.setStyle(zrUtil.defaults( |
| { |
| fill: node.getVisual('color') |
| }, |
| itemModel.getModel('itemStyle.normal').getItemStyle() |
| )); |
| |
| graphic.setHoverStyle(rect, zrUtil.extend( |
| node.getModel('itemStyle.emphasis'), |
| { |
| text: labelHoverModel.get('show') |
| ? seriesModel.getFormattedLabel(node.dataIndex, 'emphasis') || node.id |
| : '', |
| textFont: textStyleHoverModel.getFont(), |
| textFill: textStyleHoverModel.getTextColor(), |
| textPosition: labelHoverModel.get('position') |
| } |
| )); |
| |
| rect.dataIndex = node.dataIndex; |
| rect.seriesIndex = seriesModel.seriesIndex; |
| rect.dataType = 'node'; |
| |
| group.add(rect); |
| }); |
| |
| // 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.normal'); |
| var curvature = lineStyleModel.get('curveness'); |
| var n1Layout = edge.node1.getLayout(); |
| var n2Layout = edge.node2.getLayout(); |
| var edgeLayout = edge.getLayout(); |
| |
| curve.shape.extent = Math.max(1, edgeLayout.dy); |
| |
| var x1 = n1Layout.x + n1Layout.dx; |
| var y1 = n1Layout.y + edgeLayout.sy + edgeLayout.dy / 2; |
| var x2 = n2Layout.x; |
| var y2 = n2Layout.y + edgeLayout.ty + edgeLayout.dy /2; |
| var cpx1 = x1 * (1 - curvature) + x2 * curvature; |
| var cpy1 = y1; |
| var cpx2 = x1 * curvature + x2 * (1 - curvature); |
| var cpy2 = y2; |
| |
| curve.setShape({ |
| x1: x1, |
| y1: y1, |
| x2: x2, |
| y2: y2, |
| cpx1: cpx1, |
| cpy1: cpy1, |
| cpx2: cpx2, |
| cpy2: cpy2 |
| }); |
| |
| curve.setStyle(lineStyleModel.getItemStyle()); |
| graphic.setHoverStyle(curve, edge.getModel('lineStyle.emphasis').getItemStyle()); |
| |
| group.add(curve); |
| |
| }); |
| if (!this._data && seriesModel.get('animation')) { |
| group.setClipPath(createGridClipShape(group.getBoundingRect(), seriesModel, function () { |
| group.removeClipPath(); |
| })); |
| } |
| this._data = seriesModel.getData(); |
| } |
| }); |
| |
| //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; |
| } |
| }); |