NuclearDispersionSystem/ant-design-vue-jeecg/node_modules/@antv/g2/lib/geom/base.js
2023-09-14 14:47:11 +08:00

1425 lines
34 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;