401 lines
8.7 KiB
Java
401 lines
8.7 KiB
Java
/**
|
|
* @fileOverview facets of chart
|
|
* @author dxq613@gmail.com
|
|
*/
|
|
var Global = require('../global');
|
|
|
|
var Util = require('../util');
|
|
|
|
var assign = Util.assign;
|
|
var isNil = Util.isNil;
|
|
var isArray = Util.isArray;
|
|
var cloneDeep = Util.cloneDeep; // 绑定事件
|
|
|
|
var wrapBehavior = Util.wrapBehavior; // 获取绑定的事件
|
|
|
|
var getWrapBehavior = Util.getWrapBehavior;
|
|
|
|
var Base = /*#__PURE__*/function () {
|
|
var _proto = Base.prototype;
|
|
|
|
_proto.getDefaultCfg = function getDefaultCfg() {
|
|
return {
|
|
chart: null,
|
|
group: null,
|
|
|
|
/**
|
|
* 是否默认显示每个分面的title
|
|
* @type {Boolean}
|
|
*/
|
|
showTitle: true,
|
|
|
|
/**
|
|
* 是否自动修改坐标轴的信息
|
|
* @type {Boolean}
|
|
*/
|
|
autoSetAxis: true,
|
|
|
|
/**
|
|
* View 的内边框
|
|
* @type {Number|Array}
|
|
*/
|
|
padding: 10,
|
|
|
|
/**
|
|
* 遍历每个view 的回调函数
|
|
* @type {Function}
|
|
*/
|
|
eachView: null,
|
|
|
|
/**
|
|
* 分面的字段名列表
|
|
* @type {Array}
|
|
*/
|
|
fields: [],
|
|
|
|
/**
|
|
* 列值的的标题
|
|
* @type {Object}
|
|
*/
|
|
colTitle: {
|
|
offsetY: -15,
|
|
style: {
|
|
fontSize: 14,
|
|
textAlign: 'center',
|
|
fill: '#666',
|
|
fontFamily: Global.fontFamily
|
|
}
|
|
},
|
|
rowTitle: {
|
|
offsetX: 15,
|
|
style: {
|
|
fontSize: 14,
|
|
textAlign: 'center',
|
|
rotate: 90,
|
|
fill: '#666',
|
|
fontFamily: Global.fontFamily
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
function Base(cfg) {
|
|
var defaultCfg = this.getDefaultCfg();
|
|
assign(this, defaultCfg, cfg);
|
|
this.init();
|
|
}
|
|
|
|
_proto.init = function init() {
|
|
if (!this.chart) {
|
|
throw new Error('Facets Error: please specify the chart!');
|
|
}
|
|
|
|
this._bindEvent();
|
|
|
|
this.initContainer();
|
|
|
|
if (this.chart.get('data')) {
|
|
this.initViews();
|
|
}
|
|
};
|
|
|
|
_proto.initContainer = function initContainer() {
|
|
var chart = this.chart;
|
|
var frontPlot = chart.get('frontPlot');
|
|
var group = frontPlot.addGroup();
|
|
this.group = group;
|
|
};
|
|
|
|
_proto.initViews = function initViews() {
|
|
var chart = this.chart;
|
|
var data = chart.get('data');
|
|
var eachView = this.eachView;
|
|
var facets = this.generateFacets(data);
|
|
|
|
for (var i = 0; i < facets.length; i++) {
|
|
var facet = facets[i];
|
|
var region = facet.region;
|
|
var view = chart.view({
|
|
start: region.start,
|
|
end: region.end,
|
|
padding: this.padding
|
|
});
|
|
view.source(facet.data);
|
|
this.beforeProcessView(view, facet);
|
|
|
|
if (eachView) {
|
|
eachView(view, facet);
|
|
}
|
|
|
|
this.afterProcessView(view, facet);
|
|
facet.view = view;
|
|
}
|
|
|
|
this.facets = facets;
|
|
}
|
|
/**
|
|
* 处理 view 前
|
|
* @protected
|
|
*/
|
|
;
|
|
|
|
_proto.beforeProcessView = function beforeProcessView()
|
|
/* view, facet */
|
|
{}
|
|
/**
|
|
* 处理view
|
|
* @param {Object} view 视图
|
|
* @param {Object} facet 分面信息
|
|
* @protected
|
|
*/
|
|
;
|
|
|
|
_proto.afterProcessView = function afterProcessView(view, facet) {
|
|
if (this.autoSetAxis) {
|
|
this.processAxis(view, facet);
|
|
}
|
|
};
|
|
|
|
_proto.processAxis = function processAxis(view, facet) {
|
|
var viewOptions = view.get('options');
|
|
var geoms = view.get('geoms');
|
|
|
|
if ((!viewOptions.coord.type || viewOptions.coord.type === 'rect') && geoms.length) {
|
|
var field = geoms[0].get('attrOptions').position.field;
|
|
var fields = isArray(field) ? field : field.split('*').map(function (str) {
|
|
return str.trim();
|
|
});
|
|
var xField = fields[0];
|
|
var yField = fields[1];
|
|
|
|
if (isNil(viewOptions.axes)) {
|
|
viewOptions.axes = {};
|
|
}
|
|
|
|
var axes = viewOptions.axes;
|
|
|
|
if (axes !== false) {
|
|
if (xField && axes[xField] !== false) {
|
|
axes[xField] = axes[xField] || {};
|
|
this.setXAxis(xField, axes, facet);
|
|
}
|
|
|
|
if (yField && axes[yField] !== false) {
|
|
axes[yField] = axes[yField] || {};
|
|
this.setYAxis(yField, axes, facet);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
_proto.setXAxis = function setXAxis()
|
|
/* xField, axes, facet */
|
|
{};
|
|
|
|
_proto.setYAxis = function setYAxis()
|
|
/* yField, axes, facet */
|
|
{} // 默认显示各列的标题
|
|
;
|
|
|
|
_proto.renderTitle = function renderTitle(view, facet) {
|
|
this.drawColTitle(view, facet);
|
|
};
|
|
|
|
_proto.getScaleText = function getScaleText(field, value, view) {
|
|
var rst;
|
|
|
|
if (field) {
|
|
var scales = view.get('scales');
|
|
var scale = scales[field];
|
|
|
|
if (!scale) {
|
|
scale = view.createScale(field);
|
|
}
|
|
|
|
rst = scale.getText(value);
|
|
} else {
|
|
rst = value;
|
|
}
|
|
|
|
return rst;
|
|
};
|
|
|
|
_proto.drawColTitle = function drawColTitle(view, facet) {
|
|
var text = this.getScaleText(facet.colField, facet.colValue, view);
|
|
var colTextCfg = assign({
|
|
position: ['50%', '0%'],
|
|
content: text
|
|
}, this.colTitle);
|
|
view.guide().text(colTextCfg);
|
|
};
|
|
|
|
_proto.drawRowTitle = function drawRowTitle(view, facet) {
|
|
var text = this.getScaleText(facet.rowField, facet.rowValue, view);
|
|
var rowTextCfg = assign({
|
|
position: ['100%', '50%'],
|
|
content: text
|
|
}, cloneDeep(this.rowTitle));
|
|
view.guide().text(rowTextCfg);
|
|
}
|
|
/**
|
|
* 数据过滤器
|
|
* @protected
|
|
* @param {Array} conditions 过滤条件
|
|
* @return {Function} 过滤函数
|
|
*/
|
|
;
|
|
|
|
_proto.getFilter = function getFilter(conditions) {
|
|
var filter = function filter(obj) {
|
|
var filtered = true;
|
|
conditions.forEach(function (cond) {
|
|
var field = cond.field;
|
|
var value = cond.value; // const values = cond.values;
|
|
|
|
var tmp = true;
|
|
|
|
if (!isNil(value) && field) {
|
|
tmp = obj[field] === value;
|
|
}
|
|
|
|
filtered = filtered && tmp;
|
|
});
|
|
return filtered;
|
|
};
|
|
|
|
return filter;
|
|
}
|
|
/**
|
|
* 获取字段对应的值
|
|
* @protected
|
|
* @param {String} field 字段名
|
|
* @param {Array} data 数据
|
|
* @return {Array} 字段对应的值
|
|
*/
|
|
;
|
|
|
|
_proto.getFieldValues = function getFieldValues(field, data) {
|
|
var rst = [];
|
|
var tmpMap = {};
|
|
|
|
for (var i = 0; i < data.length; i++) {
|
|
var obj = data[i];
|
|
var value = obj[field];
|
|
|
|
if (!isNil(value) && !tmpMap[value]) {
|
|
rst.push(value);
|
|
tmpMap[value] = true;
|
|
}
|
|
}
|
|
|
|
return rst;
|
|
};
|
|
|
|
_proto.getRegion = function getRegion(rows, cols, xIndex, yIndex) {
|
|
var xWidth = 1 / cols; // x轴方向的每个分面的偏移
|
|
|
|
var yWidth = 1 / rows; // y轴方向的每个分面的偏移
|
|
|
|
var start = {
|
|
x: xWidth * xIndex,
|
|
y: yWidth * yIndex
|
|
};
|
|
var end = {
|
|
x: start.x + xWidth,
|
|
y: start.y + yWidth
|
|
};
|
|
return {
|
|
start: start,
|
|
end: end
|
|
};
|
|
}
|
|
/**
|
|
* 生成分面
|
|
* @protected
|
|
* @return {Array} 多个分面集合
|
|
*/
|
|
;
|
|
|
|
_proto.generateFacets = function generateFacets()
|
|
/* data */
|
|
{
|
|
return [];
|
|
};
|
|
|
|
_proto._bindEvent = function _bindEvent() {
|
|
var chart = this.chart;
|
|
chart.on('afterchangedata', wrapBehavior(this, 'onDataChange'));
|
|
chart.on('beforeclear', wrapBehavior(this, 'onClear'));
|
|
chart.on('beforedestroy', wrapBehavior(this, 'destroy'));
|
|
chart.on('beforepaint', wrapBehavior(this, 'onPaint'));
|
|
chart.on('setdata', wrapBehavior(this, 'onDataChange'));
|
|
};
|
|
|
|
_proto._clearEvent = function _clearEvent() {
|
|
var chart = this.chart;
|
|
|
|
if (chart) {
|
|
chart.off('afterchangedata', getWrapBehavior(this, 'onDataChange'));
|
|
chart.off('beforeclear', getWrapBehavior(this, 'onClear'));
|
|
chart.off('beforedestroy', getWrapBehavior(this, 'destroy'));
|
|
chart.off('beforepaint', getWrapBehavior(this, 'onPaint'));
|
|
chart.off('setdata', getWrapBehavior(this, 'onDataChange'));
|
|
}
|
|
};
|
|
|
|
_proto._clearFacets = function _clearFacets() {
|
|
var facets = this.facets;
|
|
var chart = this.chart;
|
|
|
|
if (facets) {
|
|
for (var i = 0; i < facets.length; i++) {
|
|
var facet = facets[i];
|
|
chart.removeView(facet.view);
|
|
}
|
|
}
|
|
|
|
this.facets = null;
|
|
};
|
|
|
|
_proto.onClear = function onClear() {
|
|
this.onRemove();
|
|
};
|
|
|
|
_proto.onPaint = function onPaint() {
|
|
if (this.showTitle) {
|
|
var facets = this.facets;
|
|
|
|
for (var i = 0; i < facets.length; i++) {
|
|
var facet = facets[i];
|
|
var view = facet.view;
|
|
this.renderTitle(view, facet);
|
|
}
|
|
}
|
|
};
|
|
|
|
_proto.onDataChange = function onDataChange() {
|
|
this._clearFacets();
|
|
|
|
this.initViews();
|
|
};
|
|
|
|
_proto.onRemove = function onRemove() {
|
|
this._clearFacets();
|
|
|
|
this._clearEvent();
|
|
|
|
this.group && this.group.remove();
|
|
this.chart = null;
|
|
this.facets = null;
|
|
this.group = null;
|
|
};
|
|
|
|
_proto.destroy = function destroy() {
|
|
this.onRemove();
|
|
this.destroyed = true;
|
|
};
|
|
|
|
return Base;
|
|
}();
|
|
|
|
module.exports = Base; |