blob: eda14448a44d8f9ed89b8ed0a549e44db1f25dde [file] [log] [blame]
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;
}
});