@antv/g2plot
Version:
G2 Plot, a market of plots built with the Grammar of Graphics'
258 lines • 9.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
/**
* 区域连接组件,用于堆叠柱状图和堆叠条形图
*/
var g_1 = require("@antv/g");
var _ = tslib_1.__importStar(require("@antv/util"));
var state_1 = require("../base/controller/state");
function parsePoints(shape) {
var parsedPoints = [];
var coord = shape.get('coord');
var points = shape.get('origin').points;
_.each(points, function (p) {
parsedPoints.push(coord.convertPoint(p));
});
return parsedPoints;
}
function getDefaultStyle() {
return {
areaStyle: {
opacity: 0.2,
},
lineStyle: {
lineWidth: 2,
opacity: 0.1,
},
};
}
var ConnectedArea = /** @class */ (function () {
function ConnectedArea(cfg) {
this.areas = [];
this.lines = [];
this._areaStyle = {};
this._lineStyle = {};
_.assign(this, cfg);
this._init();
}
ConnectedArea.prototype.draw = function () {
var _this = this;
var groupedShapes = this._getGroupedShapes();
_.each(groupedShapes, function (shapes, name) {
if (shapes.length > 0) {
_this._drawConnection(shapes, name);
}
});
if (this.triggerOn) {
this._addInteraction();
}
else if (this.animation) {
// 如果定义了triggerOn的方式,则组件是响应交互的,初始化为不可见状态,因此无需动画
this._initialAnimation();
}
};
ConnectedArea.prototype.clear = function () {
if (this.container) {
this.container.clear();
}
this.areas = [];
this.lines = [];
};
ConnectedArea.prototype.destory = function () {
if (this.container) {
this.container.remove();
}
};
ConnectedArea.prototype.setState = function (state, condition) {
if (state === 'active') {
this._onActive(condition);
}
if (state === 'disabled') {
this._onDisabled(condition);
}
if (state === 'selected') {
this._onSelected(condition);
}
};
ConnectedArea.prototype._init = function () {
var _this = this;
var layer = this.view.get('backgroundGroup');
this.container = layer.addGroup();
this.draw();
this.view.on('beforerender', function () {
_this.clear();
});
};
ConnectedArea.prototype._getGroupedShapes = function () {
var _this = this;
// 根据堆叠字段对shape进行分组
var values = this.view.get('scales')[this.field].values;
var geometry = this.view.get('elements')[0];
var shapes = geometry.getShapes();
// 创建分组
var groups = {};
_.each(values, function (v) {
groups[v] = [];
});
// 执行分组
_.each(shapes, function (shape) {
var origin = shape.get('origin')._origin;
var key = origin[_this.field];
groups[key].push(shape);
});
return groups;
};
ConnectedArea.prototype._drawConnection = function (shapes, name) {
// tslint:disable-next-line: prefer-for-of
var originColor = shapes[0].attr('fill');
this._areaStyle[name] = this._getShapeStyle(originColor, 'area');
this._lineStyle[name] = this._getShapeStyle(originColor, 'line');
for (var i = 0; i < shapes.length - 1; i++) {
var current = parsePoints(shapes[i]);
var next = parsePoints(shapes[i + 1]);
var areaStyle = _.mix({}, this._areaStyle[name]);
var lineStyle = _.mix({}, this._lineStyle[name]);
if (this.triggerOn) {
areaStyle.opacity = 0;
lineStyle.opacity = 0;
}
var area = this.container.addShape('path', {
attrs: _.mix({}, areaStyle, {
path: [
['M', current[2].x, current[2].y],
['L', next[1].x, next[1].y],
['L', next[0].x, next[0].y],
['L', current[3].x, current[3].y],
],
}),
name: 'connectedArea',
});
var line = this.container.addShape('path', {
attrs: _.mix({}, lineStyle, {
path: [
['M', current[2].x, current[2].y],
['L', next[1].x, next[1].y],
],
}),
name: 'connectedArea',
});
// 在辅助图形上记录数据,用以交互和响应状态量
var originData = shapes[i].get('origin')._origin;
area.set('data', originData);
line.set('data', originData);
this.areas.push(area);
this.lines.push(line);
}
};
ConnectedArea.prototype._getShapeStyle = function (originColor, shapeType) {
var styleName = shapeType + "Style";
// 如果用户自己指定了样式,则不采用默认颜色映射
if (this[styleName]) {
return this[styleName];
}
var defaultStyle = getDefaultStyle()[styleName];
var mappedStyle = { fill: originColor };
if (shapeType === 'line') {
mappedStyle = { stroke: originColor };
}
return _.mix(defaultStyle, mappedStyle);
};
ConnectedArea.prototype._addInteraction = function () {
var _this = this;
var eventName = this.triggerOn;
this.view.on("interval:" + eventName, function (e) {
var origin = e.target.get('origin')._origin[_this.field];
_this.setState('active', {
name: _this.field,
exp: origin,
});
_this.setState('disabled', {
name: _this.field,
exp: function (d) {
return d !== origin;
},
});
_this.view.get('canvas').draw();
});
// 当鼠标移动到其他区域时取消显示
this.view.on('mousemove', function (e) {
if (e.target.name !== 'interval') {
_this.setState('disabled', {
name: _this.field,
exp: function () {
return true;
},
});
}
});
};
ConnectedArea.prototype._initialAnimation = function () {
// clipIn动画
var _a = this.view.get('coord'), start = _a.start, end = _a.end, width = _a.width, height = _a.height;
var clipRect = new g_1.Shapes.Rect({
attrs: {
x: start.x,
y: end.y,
width: 0,
height: height,
},
});
this.container.attr('clip', clipRect);
this.container.setSilent('animating', true);
clipRect.animate({
width: width,
}, 600, 'easeQuadOut', function () { }, 400);
};
ConnectedArea.prototype._onActive = function (condition) {
var _this = this;
_.each(this.areas, function (area) {
var shapeData = area.get('data');
var styleField = shapeData[_this.field];
if (state_1.compare(shapeData, condition)) {
var opacity = _this._areaStyle[styleField].opacity || 1;
// area.attr('opacity',this._areaStyle[styleField].opacity || 1);
area.stopAnimate();
area.animate({ opacity: opacity }, 400, 'easeQuadOut');
}
});
_.each(this.lines, function (line) {
var shapeData = line.get('data');
var styleField = shapeData[_this.field];
if (state_1.compare(shapeData, condition)) {
var opacity = _this._lineStyle[styleField].opacity || 1;
// line.attr('opacity',this._lineStyle[styleField].opacity || 1);
line.stopAnimate();
line.animate({ opacity: opacity }, 400, 'easeQuadOut');
}
});
};
ConnectedArea.prototype._onDisabled = function (condition) {
_.each(this.areas, function (area) {
var shapeData = area.get('data');
if (state_1.compare(shapeData, condition)) {
// area.attr('opacity',0);
area.stopAnimate();
area.animate({
opacity: 0,
}, 400, 'easeQuadOut');
}
});
_.each(this.lines, function (line) {
var shapeData = line.get('data');
if (state_1.compare(shapeData, condition)) {
// line.attr('opacity',0);
line.stopAnimate();
line.animate({
opacity: 0,
}, 400, 'easeQuadOut');
}
});
};
ConnectedArea.prototype._onSelected = function (condition) {
this._onActive(condition);
};
return ConnectedArea;
}());
exports.default = ConnectedArea;
//# sourceMappingURL=connected-area.js.map