chartx
Version:
Data Visualization Chart Library
476 lines (467 loc) • 15.5 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _component = _interopRequireDefault(require("../component"));
var _canvax = _interopRequireDefault(require("canvax"));
var _trigger = _interopRequireDefault(require("../trigger"));
var _tools = require("../../utils/tools");
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
var _ = _canvax.default._,
event = _canvax.default.event;
var Circle = _canvax.default.Shapes.Circle;
var Rect = _canvax.default.Shapes.Rect;
var Line = _canvax.default.Shapes.Line;
var Legend = /*#__PURE__*/function (_Component) {
function Legend(opt, app) {
var _this;
(0, _classCallCheck2.default)(this, Legend);
_this = _callSuper(this, Legend, [opt, app]);
_this.name = "legend";
_.extend(true, _this, (0, _tools.getDefaultProps)(Legend.defaultProps()), opt);
/* data的数据结构为
[
//descartes中用到的时候还会带入yAxis
{name: "uv", color: "#ff8533", field: '' ...如果手动传入数据只需要前面这三个 enabled: true, ind: 0, } //外部只需要传field和fillStyle就行了 activate是内部状态
]
*/
_this.data = _this._getLegendData(opt);
//this.position = "top" ; //图例所在的方向top,right,bottom,left
//this.direction = "h"; //横向 top,bottom --> h left,right -- >v
if (!opt.direction && opt.position) {
if (_this.position == "left" || _this.position == "right") {
_this.direction = 'v';
} else {
_this.direction = 'h';
}
;
}
;
_this.sprite = new _canvax.default.Display.Sprite({
id: "LegendSprite",
context: {
x: _this.pos.x,
y: _this.pos.y
}
});
_this.app.stage.addChild(_this.sprite);
_this.widget();
//图例是需要自己绘制完成后,才能拿到高宽来设置自己的位置
_this.layout();
return _this;
}
(0, _inherits2.default)(Legend, _Component);
return (0, _createClass2.default)(Legend, [{
key: "_getLegendData",
value: function _getLegendData(opt) {
var legendData = opt.data;
if (legendData) {
_.each(legendData, function (item, i) {
item.enabled = true;
item.ind = i;
});
//delete opt.data;
} else {
legendData = this.app.getLegendData();
}
;
return legendData || [];
}
}, {
key: "layout",
value: function layout() {
var app = this.app;
var width = this.width + this.margin.left + this.margin.right;
var height = this.height + this.margin.top + this.margin.bottom;
var x = app.padding.left;
var y = app.padding.top;
if (this.position == "right") {
x = app.width - app.padding.right - width + this.icon.radius + this.margin.left + 10;
}
;
if (this.position == "bottom") {
y = app.height - app.padding.bottom - height + this.icon.height / 2; //TODO:这样的设置到了中线了
}
;
var layoutWidth, layoutHeight;
//然后把app的padding扩展开来
if (this.position == "left" || this.position == "right") {
// v
app.padding[this.position] += width;
layoutWidth = width;
layoutHeight = app.height - app.padding.top - app.padding.bottom;
} else if (this.position == "top" || this.position == "bottom") {
// h
app.padding[this.position] += height;
layoutWidth = app.width - app.padding.right - app.padding.left;
layoutHeight = height;
}
;
//然后计算textAlign,上面的pos.x 已经是按照默认的left计算过了的
if (this.textAlign == 'center') {
x += layoutWidth / 2 - this.width / 2;
}
;
if (this.textAlign == 'right') {
x += layoutWidth - this.width;
}
;
this.pos = {
x: x,
y: y
};
return this.pos;
}
}, {
key: "draw",
value: function draw() {
//为了在直角坐标系中,让 textAlign left的时候,图例和坐标系左侧对齐, 好看点, 用心良苦啊
var _coord = this.app.getComponent({
name: 'coord'
});
if (_coord && _coord.type == 'rect') {
if (this.textAlign == "left" && (this.position == "top" || this.position == "bottom")) {
this.pos.x = _coord.getSizeAndOrigin().origin.x + this.icon.radius;
}
;
}
;
this.setPosition();
}
}, {
key: "widget",
value: function widget() {
var me = this;
var viewWidth = this.app.width - this.app.padding.left - this.app.padding.right;
var viewHeight = this.app.height - this.app.padding.top - this.app.padding.bottom;
var maxItemWidth = 0;
var width = 0,
height = 0;
var x = 0,
y = 0;
var rows = 1;
var isOver = false; //如果legend过多
_.each(this.data, function (obj, i) {
if (isOver) return;
var _icon = me._getIconNodeEl(obj, i);
_icon.on(event.types.get(), function (e) {
//... 代理到sprit上面处理
});
var _text = obj.name;
if (me.label.format) {
_text = me.label.format(obj.name, obj);
}
;
var txt = new _canvax.default.Display.Text(_text, {
id: "legend_field_txt_" + i,
context: {
x: me.icon.radius + 3,
y: me.icon.height / 3,
textAlign: me.label.textAlign,
//"left",
textBaseline: me.label.textBaseline,
//"middle",
fillStyle: me.label.fontColor,
//"#333", //obj.color
cursor: me.label.cursor //"pointer"
}
});
txt.on(event.types.get(), function (e) {
//... 代理到sprit上面处理
});
var txtW = txt.getTextWidth();
var itemW = txtW + me.icon.radius * 2 + (i < me.data.length - 1 ? 20 : 0); //最后一个不需要+20
maxItemWidth = Math.max(maxItemWidth, itemW);
var spItemC = {
height: me.icon.height
};
if (me.direction == "v") {
if (y + me.icon.height > viewHeight) {
if (x > viewWidth * 0.3) {
isOver = true;
return;
}
;
x += maxItemWidth;
y = 0;
}
;
spItemC.x = x;
spItemC.y = y;
y += me.icon.height;
height = Math.max(height, y);
} else {
//横向排布
if (x + itemW > viewWidth) {
if (me.icon.height * (rows + 1) > viewHeight * 0.3) {
isOver = true;
return;
}
;
x = 0;
rows++;
}
;
spItemC.x = x;
spItemC.y = me.icon.height * (rows - 1);
x += itemW;
width = Math.max(width, x);
}
;
var sprite = new _canvax.default.Display.Sprite({
id: "legend_field_" + i,
context: spItemC
});
sprite.addChild(_icon);
sprite.addChild(txt);
sprite.context.width = itemW;
me.sprite.addChild(sprite);
sprite.on(event.types.get(), function (e) {
if (me.triggerEventType.indexOf(e.type) > -1 && me.activeEnabled) {
//只有一个field的时候,不支持取消
if (_.filter(me.data, function (obj) {
return obj.enabled;
}).length == 1) {
if (obj.enabled) {
return;
}
}
;
obj.enabled = !obj.enabled;
var c = !obj.enabled ? "#ccc" : obj.color || "#999";
if (obj.type == 'line') {
_icon.context.strokeStyle = c;
} else {
_icon.context.fillStyle = c;
}
if (obj.enabled) {
me.app.show(obj.field, new _trigger.default(this, obj));
} else {
me.app.hide(obj.field, new _trigger.default(this, obj));
}
;
}
;
if (me.tipsEnabled) {
if (e.type == 'mouseover' || e.type == 'mousemove') {
e.eventInfo = me._getInfoHandler(e, obj);
}
;
if (e.type == 'mouseout') {
delete e.eventInfo;
}
;
me.app.fire(e.type, e);
}
;
});
});
if (this.direction == "h") {
me.width = me.sprite.context.width = width;
me.height = me.sprite.context.height = me.icon.height * rows;
} else {
me.width = me.sprite.context.width = x + maxItemWidth;
me.height = me.sprite.context.height = height;
}
//me.width = me.sprite.context.width = width;
//me.height = me.sprite.context.height = height;
}
}, {
key: "_getIconNodeEl",
value: function _getIconNodeEl(obj, i) {
var fillStyle = !obj.enabled ? "#ccc" : obj.color || "#999";
if (this.icon.fillStyle) {
var _fillStyle = this._getProp(this.icon.fillStyle, obj);
if (_fillStyle) {
fillStyle = _fillStyle;
}
}
;
var el;
if (obj.type == 'line') {
var _obj$graph, _obj$graph$line;
var lineType = (obj === null || obj === void 0 ? void 0 : (_obj$graph = obj.graph) === null || _obj$graph === void 0 ? void 0 : (_obj$graph$line = _obj$graph.line) === null || _obj$graph$line === void 0 ? void 0 : _obj$graph$line.lineType) || "solid";
el = new Line({
id: "legend_field_icon_" + i,
context: {
start: {
x: -this.icon.radius,
y: this.icon.height / 3 - 1
},
end: {
x: -this.icon.radius + this.icon.radius * 2,
y: this.icon.height / 3 - 1
},
strokeStyle: fillStyle,
lineWidth: 2,
cursor: "pointer",
lineType: lineType,
lineDash: [2, 4]
}
});
} else if (obj.type == 'bar') {
el = new Rect({
id: "legend_field_icon_" + i,
context: {
x: -this.icon.radius,
y: this.icon.height / 3 - this.icon.radius,
fillStyle: fillStyle,
width: this.icon.radius * 2,
height: this.icon.radius * 2,
radius: [3, 3, 3, 3],
cursor: "pointer"
}
});
} else {
el = new Circle({
id: "legend_field_icon_" + i,
context: {
x: 0,
y: this.icon.height / 3,
fillStyle: fillStyle,
r: this.icon.radius,
cursor: "pointer"
}
});
}
;
return el;
}
}, {
key: "_getInfoHandler",
value: function _getInfoHandler(e, data) {
return {
type: "legend",
triggerType: 'legend',
trigger: 'this',
//this,
tipsEnabled: this.tipsEnabled,
nodes: [{
name: data.name,
fillStyle: data.color
}]
};
}
}, {
key: "_getProp",
value: function _getProp(prop, nodeData) {
var _prop = prop;
if (_.isArray(prop)) {
_prop = prop[nodeData.ind];
}
;
if (_.isFunction(prop)) {
_prop = prop.apply(this, [nodeData]);
}
;
return _prop;
}
}], [{
key: "defaultProps",
value: function defaultProps() {
return {
data: {
detail: '图例数据',
default: [],
documentation: '\
数据结构为:{name: "uv", color: "#ff8533", field: "" ...}\
如果手动传入数据只需要前面这三个 enabled: true, ind: 0\
外部只需要传field和fillStyle就行了\
'
},
position: {
detail: '图例位置',
documentation: '图例所在的方向top,right,bottom,left',
default: 'top'
},
direction: {
detail: '图例布局方向',
default: 'h',
documentation: '横向 top,bottom --> h left,right -- >v'
},
textAlign: {
detail: '水平方向的对其,默认居左对其',
default: 'left',
documentation: '可选left,center,right'
},
verticalAlign: {
detail: '垂直方向的对其方式,默认居中(待实现)',
default: 'middle',
documentation: '可选top,middle,bottom'
},
icon: {
detail: '图标设置',
propertys: {
height: {
detail: '高',
default: 26
},
width: {
detail: '图标宽',
default: 'auto'
},
radius: {
detail: '图标(circle)半径',
default: 5
},
lineWidth: {
detail: '图标描边宽度',
default: 1
},
fillStyle: {
detail: '图标颜色,一般会从data里面取,这里是默认色',
default: null
}
}
},
label: {
detail: '文本配置',
propertys: {
textAlign: {
detail: '水平对齐方式',
default: 'left'
},
textBaseline: {
detail: '文本基线对齐方式',
default: 'middle'
},
fontColor: {
detail: '文本颜色',
default: '#333333'
},
cursor: {
detail: '鼠标样式',
default: 'pointer'
},
format: {
detail: '文本格式化处理函数',
default: null
}
}
},
triggerEventType: {
detail: '触发事件',
default: 'click,tap'
},
activeEnabled: {
detail: '是否启动图例的交互事件',
default: true
},
tipsEnabled: {
detail: '是否开启图例的tips',
default: false
}
};
}
}]);
}(_component.default);
_component.default.registerComponent(Legend, 'legend');
var _default = exports.default = Legend;