NuclearDispersionSystem/ant-design-vue-jeecg/node_modules/@antv/g2/lib/geom/base.js

1425 lines
34 KiB
Java
Raw Normal View History

2023-09-14 14:47:11 +08:00
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
/**
* @fileOverview 所有 Geometry 的基类
* @author dxq613@gmail.com
*/
var Attr = require('@antv/attr/lib');
var Adjust = require('@antv/adjust/lib');
var Base = require('../base');
var Util = require('../util');
var Global = require('../global');
var Labels = require('./label/index');
var Shape = require('./shape/shape');
var TooltipMixin = require('./mixin/tooltip');
var ActiveMixin = require('./mixin/active');
var SelectMixin = require('./mixin/select');
var parseFields = require('./util/parse-fields');
var GROUP_ATTRS = ['color', 'shape', 'size'];
var FIELD_ORIGIN = '_origin'; // 转换成对象的数组 [{type: 'adjust'}]
function parseAdjusts(adjusts) {
// 如果是字符串或者对象转换成数组
if (Util.isString(adjusts) || Util.isPlainObject(adjusts)) {
adjusts = [adjusts];
}
Util.each(adjusts, function (adjust, index) {
if (!Util.isObject(adjust)) {
adjusts[index] = {
type: adjust
};
}
});
return adjusts;
}
/**
* 几何标记
* @class Geom
*/
var GeomBase = /*#__PURE__*/function (_Base) {
_inheritsLoose(GeomBase, _Base);
var _proto = GeomBase.prototype;
/**
* 获取默认的配置属性
* @protected
* @return {Object} 默认属性
*/
_proto.getDefaultCfg = function getDefaultCfg() {
return {
/**
* 标记 _id 用于区分执行动画
* @type {String}
*/
_id: null,
/**
* 类型
* @type {String}
*/
type: 'base',
/**
* 坐标系
* @type {Object}
*/
coord: null,
/**
* 属性映射集
* @protected
* @type {Object}
*/
attrs: {},
/**
* 所属的View
* @type {View}
*/
view: null,
/**
* 几何标记显示的数据
* @type {Array}
*/
data: [],
/**
* 相关的度量
* @type {Object}
*/
scales: {},
/**
* 绘图容器
* @type {Object}
*/
container: null,
/**
* 文本容器
* @type {Object}
*/
labelContainer: null,
/**
* 图形容器
* @type {Object}
*/
shapeContainer: null,
/**
* 几何标记的一些配置项用于延迟生成图表
* @type {Object}
*/
attrOptions: {},
// 样式配置项
styleOptions: null,
// 选中时的配置项
selectedOptions: null,
// active 时的配置项
activedOptions: null,
/**
* 某些类存在默认的adjust不能更改 adjust
* @type {Boolean}
*/
hasDefaultAdjust: false,
// 数据调整类型
adjusts: null,
/**
* 使用形状的类型
* @protected
* @type {String}
*/
shapeType: null,
/**
* 是否生成多个点来绘制图形
* @protected
* @type {Boolean}
*/
generatePoints: false,
/**
* 数据是否进行排序
* @type {Boolean}
*/
sortable: false,
labelCfg: null,
/**
* 是否共享 tooltip
* @type {Boolean}
*/
shareTooltip: true,
tooltipCfg: null,
/**
* 是否执行动画默认执行
* @type {Boolean}
*/
animate: true,
/**
* 动画配置
* @type {[type]}
*/
animateCfg: null,
visible: true
};
};
function GeomBase(cfg) {
var _this;
_this = _Base.call(this, cfg) || this;
_this.viewTheme = _this.get('viewTheme');
Util.assign(_assertThisInitialized(_this), TooltipMixin, ActiveMixin, SelectMixin);
if (_this.get('container')) {
_this._initContainer();
}
_this._initOptions();
return _this;
} // 初始化时对配置项的格式化
_proto._initOptions = function _initOptions() {
var adjusts = this.get('adjusts');
if (adjusts) {
adjusts = parseAdjusts(adjusts);
this.set('adjusts', adjusts);
}
};
_proto._createScale = function _createScale(field, data) {
var scales = this.get('scales');
var scale = scales[field];
if (!scale) {
scale = this.get('view').createScale(field, data);
scales[field] = scale;
}
return scale;
};
_proto._setAttrOptions = function _setAttrOptions(attrName, attrCfg) {
var options = this.get('attrOptions');
options[attrName] = attrCfg;
};
_proto._createAttrOption = function _createAttrOption(attrName, field, cfg, defaultValues) {
var attrCfg = {};
attrCfg.field = field;
if (cfg) {
if (Util.isFunction(cfg)) {
attrCfg.callback = cfg;
} else {
attrCfg.values = cfg;
}
} else if (attrName !== 'color') {
attrCfg.values = defaultValues;
}
this._setAttrOptions(attrName, attrCfg);
}
/**
* 位置属性映射
* @chainable
* @param {String} field 字段名
* @return {Geom} geom 当前几何标记
*/
;
_proto.position = function position(field) {
this._setAttrOptions('position', {
field: field
});
return this;
}
/**
* 颜色属性映射
* @chainable
* @param {String} field 字段名
* @param {Array|Function} values 颜色的数组或者回调函数
* @return {Geom} geom 当前几何标记
*/
;
_proto.color = function color(field, values) {
var viewTheme = this.viewTheme || Global;
this._createAttrOption('color', field, values, viewTheme.colors);
return this;
}
/**
* 大小属性映射
* @chainable
* @param {String} field 字段名
* @param {Array|Function} values 大小的数组或者回调函数
* @return {Geom} geom 当前几何标记
*/
;
_proto.size = function size(field, values) {
var viewTheme = this.viewTheme || Global;
this._createAttrOption('size', field, values, viewTheme.sizes);
return this;
}
/**
* 形状属性映射
* @chainable
* @param {String} field 字段名
* @param {Array|Function} values 大小的数组或者回调函数
* @return {Geom} geom 当前几何标记
*/
;
_proto.shape = function shape(field, values) {
var viewTheme = this.viewTheme || Global;
var type = this.get('type');
var shapes = viewTheme.shapes[type] || [];
this._createAttrOption('shape', field, values, shapes);
return this;
}
/**
* 透明度属性映射
* @chainable
* @param {String} field 字段名
* @param {Array|Function} values 透明度的数组或者回调函数
* @return {Geom} geom 当前几何标记
*/
;
_proto.opacity = function opacity(field, values) {
var viewTheme = this.viewTheme || Global;
this._createAttrOption('opacity', field, values, viewTheme.opacities);
return this;
};
_proto.style = function style(field, cfg) {
var styleOptions = this.get('styleOptions');
if (!styleOptions) {
styleOptions = {};
this.set('styleOptions', styleOptions);
}
if (Util.isObject(field)) {
cfg = field;
field = null;
}
var fields;
if (field) {
fields = parseFields(field);
}
styleOptions.fields = fields;
styleOptions.style = cfg;
return this;
};
_proto.label = function label(field, callback, cfg) {
var self = this;
var labelCfg = self.get('labelCfg'); // const scales = Util.map(self.get('labelCfg').fields, field => self._createScale(field));
if (!labelCfg) {
labelCfg = {};
self.set('labelCfg', labelCfg);
}
var fields;
if (field) {
fields = parseFields(field);
}
labelCfg.fields = fields; // 如果存在回调函数
if (Util.isFunction(callback)) {
if (!cfg) {
cfg = {};
}
labelCfg.callback = callback;
} else if (Util.isObject(callback)) {
// 如果没有设置回调函数
cfg = callback;
}
labelCfg.globalCfg = cfg;
return this;
};
_proto.tooltip = function tooltip(field, cfg) {
var tooltipCfg = this.get('tooltipCfg');
if (!tooltipCfg) {
tooltipCfg = {};
}
if (field === false) {
// geom 关闭 tooltip
this.set('tooltipCfg', false);
} else {
var tooltipFields;
if (field) {
tooltipFields = parseFields(field);
}
tooltipCfg.fields = tooltipFields;
tooltipCfg.cfg = cfg;
}
this.set('tooltipCfg', tooltipCfg);
return this;
};
_proto.animate = function animate(cfg) {
this.set('animateCfg', cfg);
return this;
}
/**
* 是否允许使用默认的图形激活交互
* @param {Boolean} enable 是否允许激活开关
* @param {Object} cfg 激活的配置项
* @return {Geom} 返回 geom 自身
*/
;
_proto.active = function active(enable, cfg) {
if (enable === false) {
this.set('allowActive', false);
} else if (Util.isObject(enable)) {
this.set('allowActive', true);
this.set('activedOptions', enable);
} else {
this.set('allowActive', true);
this.set('activedOptions', cfg);
}
return this;
}
/**
* geometry 进行数据调整
* @chainable
* @param {String|Array|null} adjusts 数据调整的类型
* @return {Object} geometry 对象
*/
;
_proto.adjust = function adjust(adjusts) {
if (!this.get('hasDefaultAdjust')) {
if (adjusts) {
adjusts = parseAdjusts(adjusts);
}
this.set('adjusts', adjusts);
}
return this;
}
/**
* 设置图形的选中模式
* @param {Boolean|Object} enable 布尔类型用于模式开关对象类型用于配置
* @param {Object} cfg 选中配置项
* @return {Geom} 返回 geom 自身
*/
;
_proto.select = function select(enable, cfg) {
if (enable === false) {
this.set('allowSelect', false);
} else if (Util.isObject(enable)) {
this.set('allowSelect', true);
this.set('selectedOptions', enable);
} else {
this.set('allowSelect', true);
this.set('selectedOptions', cfg);
}
return this;
};
_proto.hasAdjust = function hasAdjust(adjustType) {
var self = this;
var adjusts = self.get('adjusts');
if (!adjustType) {
return false;
}
var rst = false;
Util.each(adjusts, function (adjust) {
if (adjust.type === adjustType) {
rst = true;
return false;
}
});
return rst;
};
_proto.hasStack = function hasStack() {
var isStacked = this.get('isStacked');
if (Util.isNil(isStacked)) {
isStacked = this.hasAdjust('stack');
this.set('isStacked', isStacked);
}
return isStacked;
};
_proto.isInCircle = function isInCircle() {
var coord = this.get('coord');
return coord && coord.isPolar;
};
_proto._initContainer = function _initContainer() {
var self = this;
var shapeContainer = self.get('shapeContainer');
if (!shapeContainer) {
var container = self.get('container');
var view = self.get('view');
var viewId = view && view.get('_id');
shapeContainer = container.addGroup({
viewId: viewId,
visible: self.get('visible')
});
self.set('shapeContainer', shapeContainer);
}
};
_proto.init = function init() {
var self = this;
self._initContainer();
self._initAttrs();
if (self.get('tooltipCfg') && self.get('tooltipCfg').fields) {
var tooltipFields = self.get('tooltipCfg').fields;
Util.each(tooltipFields, function (field) {
self._createScale(field);
});
}
var dataArray = self._processData();
if (self.get('adjusts')) {
self._adjust(dataArray);
}
self.set('dataArray', dataArray);
} // step 1: init attrs
;
_proto._initAttrs = function _initAttrs() {
var self = this;
var attrs = self.get('attrs');
var attrOptions = self.get('attrOptions');
var coord = self.get('coord');
var viewTheme = self.viewTheme || Global;
var isPie = false;
for (var type in attrOptions) {
if (attrOptions.hasOwnProperty(type)) {
var option = attrOptions[type];
var className = Util.upperFirst(type);
var fields = parseFields(option.field);
if (type === 'position') {
option.coord = coord; // 饼图坐标系下,填充一维
if (fields.length === 1 && coord.type === 'theta') {
fields.unshift('1');
isPie = true;
}
}
var scales = [];
for (var i = 0; i < fields.length; i++) {
var field = fields[i];
var scale = self._createScale(field);
if (type === 'color' && Util.isNil(option.values)) {
// 设置 color 的默认色值
if (scale.values.length <= 8) {
option.values = isPie ? viewTheme.colors_pie : viewTheme.colors;
} else if (scale.values.length <= 16) {
option.values = isPie ? viewTheme.colors_pie_16 : viewTheme.colors_16;
} else {
option.values = viewTheme.colors_24;
}
if (Util.isNil(option.values)) {
option.values = viewTheme.colors; // 防止主题没有声明诸如 colors_pie 的属性
}
}
scales.push(scale);
} // 饼图需要填充满整个空间
if (coord.type === 'theta' && type === 'position' && scales.length > 1) {
var yScale = scales[1];
var min = 0;
var max = Math.max.apply(null, yScale.values);
if (!isFinite(max)) {
max = 1;
}
yScale.change({
nice: false,
min: min,
max: max
});
}
option.scales = scales;
var attr = new Attr[className](option);
attrs[type] = attr;
}
}
} // step 2: 处理数据
;
_proto._processData = function _processData() {
var self = this;
var data = this.get('data');
var dataArray = [];
var groupedArray = this._groupData(data);
for (var i = 0; i < groupedArray.length; i++) {
var subData = groupedArray[i];
var tempData = self._saveOrigin(subData);
dataArray.push(self._numberic(tempData));
}
return dataArray;
} // step 2.1 数据分组
;
_proto._groupData = function _groupData(data) {
var groupScales = this._getGroupScales();
var fields = groupScales.map(function (scale) {
return scale.field;
});
return Util.Array.group(data, fields);
} // step 2.2 数据调整前保存原始数据
;
_proto._saveOrigin = function _saveOrigin(data) {
var rst = [];
for (var i = 0; i < data.length; i++) {
var origin = data[i];
var obj = {};
for (var k in origin) {
obj[k] = origin[k];
} // const obj = Util.mix({}, origin);
obj[FIELD_ORIGIN] = origin;
rst.push(obj);
}
return rst;
} // step 2.3 将分类数据翻译成数据, 仅对位置相关的度量进行数字化处理
;
_proto._numberic = function _numberic(data) {
var positionAttr = this.getAttr('position');
var scales = positionAttr.scales;
var result = [];
for (var j = 0; j < data.length; j++) {
var obj = data[j];
var isValidate = true;
for (var i = 0; i < Math.min(2, scales.length); i++) {
var scale = scales[i];
if (scale.isCategory) {
var field = scale.field;
obj[field] = scale.translate(obj[field]);
if (Number.isNaN(obj[field])) {
// 当分类为 NaN 时,说明该条数据不在定义域内,需要过滤掉
isValidate = false;
}
}
}
if (isValidate) {
result.push(obj);
}
}
return result;
};
_proto._getGroupScales = function _getGroupScales() {
var self = this;
var scales = self.get('groupScales');
if (!scales) {
scales = [];
var attrs = self.get('attrs');
Util.each(attrs, function (attr) {
if (GROUP_ATTRS.includes(attr.type)) {
var attrScales = attr.scales;
Util.each(attrScales, function (scale) {
if (scale.isCategory && Util.indexOf(scales, scale) === -1) {
scales.push(scale);
}
});
}
});
self.set('groupScales', scales);
}
return scales;
};
_proto._updateStackRange = function _updateStackRange(field, scale, dataArray) {
var mergeArray = Util.Array.merge(dataArray);
var min = scale.min;
var max = scale.max;
for (var i = 0; i < mergeArray.length; i++) {
var obj = mergeArray[i]; // 过滤掉非法数据
if (!Util.isArray(obj[field])) {
continue;
}
var tmpMin = Math.min.apply(null, obj[field]);
var tmpMax = Math.max.apply(null, obj[field]);
if (tmpMin < min) {
min = tmpMin;
}
if (tmpMax > max) {
max = tmpMax;
}
}
if (min < scale.min || max > scale.max) {
scale.change({
min: min,
max: max
});
}
} // step 2.2 调整数据
;
_proto._adjust = function _adjust(dataArray) {
// 当数据为空的时候,就不需要对数据进行调整了
if (!dataArray || !dataArray.length) {
return;
}
var self = this;
var adjusts = self.get('adjusts');
var viewTheme = this.viewTheme || Global;
var yScale = self.getYScale();
var xScale = self.getXScale();
var xField = xScale.field;
var yField = yScale ? yScale.field : null;
Util.each(adjusts, function (adjust) {
var adjustCfg = Util.mix({
xField: xField,
yField: yField
}, adjust);
var adjustType = Util.upperFirst(adjust.type);
if (adjustType === 'Dodge') {
var adjustNames = [];
if (xScale.isCategory || xScale.isIdentity) {
adjustNames.push('x');
} else if (!yScale) {
adjustNames.push('y');
} else {
throw new Error('dodge is not support linear attribute, please use category attribute!');
}
adjustCfg.adjustNames = adjustNames;
adjustCfg.dodgeRatio = adjustCfg.dodgeRatio || viewTheme.widthRatio.column;
/* if (self.isInCircle()) {
adjustCfg.dodgeRatio = 1;
adjustCfg.marginRatio = 0;
}*/
} else if (adjustType === 'Stack') {
var coord = self.get('coord');
if (!yScale) {
// 一维的情况下获取高度和默认size
adjustCfg.height = coord.getHeight();
var size = self.getDefaultValue('size') || 3;
adjustCfg.size = size;
} // 不进行 transpose 时,用户又没有设置这个参数时,默认从上向下
if (!coord.isTransposed && Util.isNil(adjustCfg.reverseOrder)) {
adjustCfg.reverseOrder = true;
}
}
var adjustElement = new Adjust[adjustType](adjustCfg);
adjustElement.processAdjust(dataArray);
if (adjustType === 'Stack' && yScale) {
self._updateStackRange(yField, yScale, dataArray);
}
});
}
/**
* @internal 设置coord通常外部容器变化时coord 会发生变化
* @param {Object} coord 坐标系
*/
;
_proto.setCoord = function setCoord(coord) {
this.set('coord', coord);
var position = this.getAttr('position');
var shapeContainer = this.get('shapeContainer');
shapeContainer.setMatrix(coord.matrix);
if (position) {
position.coord = coord;
}
} // step 3 绘制
;
_proto.paint = function paint() {
var self = this;
var dataArray = self.get('dataArray');
var mappedArray = [];
var shapeFactory = self.getShapeFactory();
shapeFactory.setCoord(self.get('coord'));
self.set('shapeFactory', shapeFactory);
var shapeContainer = self.get('shapeContainer');
self._beforeMapping(dataArray);
for (var i = 0; i < dataArray.length; i++) {
var data = dataArray[i];
var index = i;
data = self._mapping(data);
mappedArray.push(data);
self.draw(data, shapeContainer, shapeFactory, index);
}
if (self.get('labelCfg')) {
self._addLabels(Util.union.apply(null, mappedArray), shapeContainer.get('children'));
}
if (!self.get('sortable')) {
self._sort(mappedArray); // 便于数据的查找,需要对数据进行排序,用于 geom.findPoint()
} else {
self.set('dataArray', mappedArray);
}
};
_proto._sort = function _sort(mappedArray) {
var self = this;
var xScale = self.getXScale();
var xField = xScale.field;
Util.each(mappedArray, function (itemArr) {
itemArr.sort(function (obj1, obj2) {
return xScale.translate(obj1[FIELD_ORIGIN][xField]) - xScale.translate(obj2[FIELD_ORIGIN][xField]);
});
});
self.set('dataArray', mappedArray);
} // step 3.1 before mapping
;
_proto._beforeMapping = function _beforeMapping(dataArray) {
var self = this;
if (self.get('sortable')) {
var xScale = self.getXScale();
var field = xScale.field;
Util.each(dataArray, function (data) {
data.sort(function (v1, v2) {
return xScale.translate(v1[field]) - xScale.translate(v2[field]);
});
});
}
if (self.get('generatePoints')) {
Util.each(dataArray, function (data) {
self._generatePoints(data);
});
Util.each(dataArray, function (data, index) {
var nextData = dataArray[index + 1];
if (nextData) {
data[0].nextPoints = nextData[0].points;
}
});
}
} // step 3.2 add labels
;
_proto._addLabels = function _addLabels(points, shapes) {
var self = this;
var type = self.get('type');
var viewTheme = self.get('viewTheme') || Global;
var coord = self.get('coord');
var C = Labels.getLabelsClass(coord.type, type);
var container = self.get('container');
var scales = Util.map(self.get('labelCfg').fields, function (field) {
return self._createScale(field);
});
var labelContainer = container.addGroup(C, {
_id: this.get('_id'),
labelCfg: Util.mix({
scales: scales
}, self.get('labelCfg')),
coord: coord,
geom: self,
geomType: type,
yScale: self.getYScale(),
viewTheme: viewTheme,
visible: self.get('visible')
});
labelContainer.showLabels(points, shapes);
self.set('labelContainer', labelContainer);
}
/**
* @protected
* 获取图形的工厂类
* @return {Object} 工厂类对象
*/
;
_proto.getShapeFactory = function getShapeFactory() {
var shapeFactory = this.get('shapeFactory');
if (!shapeFactory) {
var shapeType = this.get('shapeType');
shapeFactory = Shape.getShapeFactory(shapeType);
this.set('shapeFactory', shapeFactory);
}
return shapeFactory;
} // step 3.2 generate points
;
_proto._generatePoints = function _generatePoints(data) {
var self = this;
var shapeFactory = self.getShapeFactory();
var shapeAttr = self.getAttr('shape');
for (var i = 0; i < data.length; i++) {
var obj = data[i];
var cfg = self.createShapePointsCfg(obj);
var shape = shapeAttr ? self._getAttrValues(shapeAttr, obj) : null;
var points = shapeFactory.getShapePoints(shape, cfg);
obj.points = points;
}
}
/**
* 获取图形对应点的配置项
* @protected
* @param {Object} obj 数据对象
* @return {Object} cfg 获取图形对应点的配置项
*/
;
_proto.createShapePointsCfg = function createShapePointsCfg(obj) {
var xScale = this.getXScale();
var yScale = this.getYScale();
var x = this._normalizeValues(obj[xScale.field], xScale);
var y; // 存在没有 y 的情况
if (yScale) {
y = this._normalizeValues(obj[yScale.field], yScale);
} else {
y = obj.y ? obj.y : 0.1;
}
return {
x: x,
y: y,
y0: yScale ? yScale.scale(this.getYMinValue()) : undefined
};
}
/**
* @protected
* 如果y轴的最小值小于0则返回0否则返回最小值
* @return {Number} y轴上的最小值
*/
;
_proto.getYMinValue = function getYMinValue() {
var yScale = this.getYScale();
var min = yScale.min,
max = yScale.max;
var value;
if (min >= 0) {
value = min;
} else if (max <= 0) {
// 当值全位于负区间时,需要保证 ymin 在区域内,不可为 0
value = max;
} else {
value = 0;
}
return value;
} // 将数据归一化
;
_proto._normalizeValues = function _normalizeValues(values, scale) {
var rst = [];
if (Util.isArray(values)) {
for (var i = 0; i < values.length; i++) {
var v = values[i];
rst.push(scale.scale(v));
}
} else {
rst = scale.scale(values);
}
return rst;
} // step 3.2 mapping
;
_proto._mapping = function _mapping(data) {
var self = this;
var attrs = self.get('attrs');
var mappedData = [];
for (var i = 0; i < data.length; i++) {
var record = data[i];
var newRecord = {};
newRecord[FIELD_ORIGIN] = record[FIELD_ORIGIN];
newRecord.points = record.points;
newRecord.nextPoints = record.nextPoints;
for (var k in attrs) {
if (attrs.hasOwnProperty(k)) {
var attr = attrs[k];
var names = attr.names;
var values = self._getAttrValues(attr, record);
if (names.length > 1) {
// position 之类的生成多个字段的属性
for (var j = 0; j < values.length; j++) {
var val = values[j];
var name = names[j];
newRecord[name] = Util.isArray(val) && val.length === 1 ? val[0] : val; // 只有一个值时返回第一个属性值
}
} else {
newRecord[names[0]] = values.length === 1 ? values[0] : values;
}
}
}
mappedData.push(newRecord);
}
return mappedData;
} // 获取属性映射的值
;
_proto._getAttrValues = function _getAttrValues(attr, record) {
var scales = attr.scales;
var params = [];
for (var i = 0; i < scales.length; i++) {
var scale = scales[i];
var field = scale.field;
if (scale.type === 'identity') {
params.push(scale.value);
} else {
params.push(record[field]);
}
}
var values = attr.mapping.apply(attr, params);
return values;
};
_proto.getAttrValue = function getAttrValue(attrName, record) {
var attr = this.getAttr(attrName);
var rst = null;
if (attr) {
var values = this._getAttrValues(attr, record);
rst = values[0];
}
return rst;
};
_proto.getDefaultValue = function getDefaultValue(attrName) {
var value = this.get(attrName);
var attr = this.getAttr(attrName);
if (attr) {
var scale = attr.getScale(attrName);
if (scale.type === 'identity') {
value = scale.value;
}
}
return value;
}
/**
* step 3.3 draw
* @protected
* @param {Array} data 绘制图形
* @param {Object} container 绘图容器
* @param {Object} shapeFactory 绘制图形的工厂类
* @param {Number} index 每个 shape 的索引值
*/
;
_proto.draw = function draw(data, container, shapeFactory, index) {
var self = this;
for (var i = 0; i < data.length; i++) {
var obj = data[i];
self.drawPoint(obj, container, shapeFactory, index + i);
}
};
_proto.getCallbackCfg = function getCallbackCfg(fields, cfg, origin) {
if (!fields) {
return cfg;
}
var tmpCfg = {};
var params = fields.map(function (field) {
return origin[field];
});
Util.each(cfg, function (v, k) {
if (Util.isFunction(v)) {
tmpCfg[k] = v.apply(null, params);
} else {
tmpCfg[k] = v;
}
});
return tmpCfg;
};
_proto._getShapeId = function _getShapeId(dataObj) {
var id = this.get('_id');
var keyFields = this.get('keyFields');
if (keyFields && keyFields.length > 0) {
Util.each(keyFields, function (key) {
id += '-' + dataObj[key];
});
} else {
var type = this.get('type');
var xScale = this.getXScale();
var yScale = this.getYScale();
var xField = xScale.field || 'x';
var yField = yScale.field || 'y';
var yVal = dataObj[yField];
var xVal;
if (xScale.isIdentity) {
xVal = xScale.value;
} else {
xVal = dataObj[xField];
}
if (type === 'interval' || type === 'schema') {
id += '-' + xVal;
} else if (type === 'line' || type === 'area' || type === 'path') {
id += '-' + type;
} else {
id += '-' + xVal + '-' + yVal;
}
var groupScales = this._getGroupScales();
if (!Util.isEmpty(groupScales)) {
Util.each(groupScales, function (groupScale) {
var field = groupScale.field;
if (groupScale.type !== 'identity') {
id += '-' + dataObj[field];
}
});
}
}
return id;
};
_proto.getDrawCfg = function getDrawCfg(obj) {
var self = this;
var cfg = {
origin: obj,
x: obj.x,
y: obj.y,
color: obj.color,
size: obj.size,
shape: obj.shape,
isInCircle: self.isInCircle(),
opacity: obj.opacity
};
var styleOptions = self.get('styleOptions');
if (styleOptions && styleOptions.style) {
cfg.style = self.getCallbackCfg(styleOptions.fields, styleOptions.style, obj[FIELD_ORIGIN]);
}
if (self.get('generatePoints')) {
cfg.points = obj.points;
cfg.nextPoints = obj.nextPoints;
}
if (self.get('animate')) {
// _id 字段仅用于动画
cfg._id = self._getShapeId(obj[FIELD_ORIGIN]);
}
return cfg;
};
_proto.appendShapeInfo = function appendShapeInfo(shape, index) {
if (shape) {
shape.setSilent('index', index);
shape.setSilent('coord', this.get('coord'));
if (this.get('animate') && this.get('animateCfg')) {
shape.setSilent('animateCfg', this.get('animateCfg'));
}
}
};
_proto._applyViewThemeShapeStyle = function _applyViewThemeShapeStyle(cfg, shape, shapeFactory) {
// applying view theme
var self = this;
var viewTheme = self.viewTheme || Global;
var shapeName = shapeFactory.name;
if (shape) {
if (shape && (shape.indexOf('hollow') > -1 || shape.indexOf('liquid') > -1)) {
shapeName = "hollow" + Util.upperFirst(shapeName);
}
} else if (shapeFactory.defaultShapeType.indexOf('hollow') > -1) {
shapeName = "hollow" + Util.upperFirst(shapeName);
}
var defaultStyle = viewTheme.shape[shapeName] || {};
cfg.style = Util.mix({}, defaultStyle, cfg.style);
};
_proto.drawPoint = function drawPoint(obj, container, shapeFactory, index) {
var self = this;
var shape = obj.shape;
var cfg = self.getDrawCfg(obj);
self._applyViewThemeShapeStyle(cfg, shape, shapeFactory);
var geomShape = shapeFactory.drawShape(shape, cfg, container);
self.appendShapeInfo(geomShape, index);
}
/**
* 获取属性
* @protected
* @param {String} name 属性名
* @return {Scale} 度量
*/
;
_proto.getAttr = function getAttr(name) {
return this.get('attrs')[name];
}
/**
* 获取 x 对应的度量
* @return {Scale} x 对应的度量
*/
;
_proto.getXScale = function getXScale() {
return this.getAttr('position').scales[0];
}
/**
* 获取 y 对应的度量
* @return {Scale} y 对应的度量
*/
;
_proto.getYScale = function getYScale() {
return this.getAttr('position').scales[1];
};
_proto.getShapes = function getShapes() {
var result = [];
var shapeContainer = this.get('shapeContainer');
var children = shapeContainer.get('children');
Util.each(children, function (child) {
if (child.get('origin')) {
// 过滤 label
result.push(child);
}
});
return result;
};
_proto.getAttrsForLegend = function getAttrsForLegend() {
var attrs = this.get('attrs');
var rst = [];
Util.each(attrs, function (attr) {
if (GROUP_ATTRS.includes(attr.type)) {
rst.push(attr);
}
});
return rst;
};
_proto.getFieldsForLegend = function getFieldsForLegend() {
var fields = [];
var attrOptions = this.get('attrOptions');
Util.each(GROUP_ATTRS, function (attrName) {
var attrCfg = attrOptions[attrName];
if (attrCfg && attrCfg.field && Util.isString(attrCfg.field)) {
fields = fields.concat(attrCfg.field.split('*'));
}
});
return Util.uniq(fields);
};
_proto.changeVisible = function changeVisible(visible, stopDraw) {
var me = this;
me.set('visible', visible);
var shapeContainer = this.get('shapeContainer');
if (shapeContainer) {
shapeContainer.set('visible', visible);
}
var labelContainer = this.get('labelContainer');
if (labelContainer) {
labelContainer.set('visible', visible);
}
if (!stopDraw && shapeContainer) {
var canvas = shapeContainer.get('canvas');
canvas.draw();
}
};
_proto.reset = function reset() {
this.set('attrOptions', {});
this.clearInner();
};
_proto.clearInner = function clearInner() {
this.clearActivedShapes();
this.clearSelected();
var shapeContainer = this.get('shapeContainer');
shapeContainer && shapeContainer.clear(); // 由于 Labels 对应的模块需要生成group所以这个地方需要删除
var labelContainer = this.get('labelContainer');
labelContainer && labelContainer.remove();
this.set('attrs', {});
this.set('groupScales', null); // if (!this.get('hasDefaultAdjust')) {
// this.set('adjusts', null);
// }
this.set('labelContainer', null);
this.set('xDistance', null);
this.set('isStacked', null);
};
_proto.clear = function clear() {
this.clearInner();
this.set('scales', {});
};
_proto.destroy = function destroy() {
this.clear();
var shapeContainer = this.get('shapeContainer');
shapeContainer && shapeContainer.remove();
this.offEvents();
_Base.prototype.destroy.call(this);
};
_proto.bindEvents = function bindEvents() {
if (this.get('view')) {
this._bindActiveAction();
this._bindSelectedAction();
}
};
_proto.offEvents = function offEvents() {
if (this.get('view')) {
this._offActiveAction();
this._offSelectedAction();
}
};
return GeomBase;
}(Base);
module.exports = GeomBase;