NuclearDispersionSystem/ant-design-vue-jeecg/node_modules/@antv/component/lib/legend/cat-html.js

653 lines
21 KiB
Java
Raw Normal View History

2023-09-14 14:47:11 +08:00
function _createSuper(Derived) { return function () { var Super = _getPrototypeOf(Derived), result; if (_isNativeReflectConstruct()) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
var Util = require('../util');
var Category = require('./category');
var _require = require('../const'),
FONT_FAMILY = _require.FONT_FAMILY;
var DomUtil = Util.DomUtil;
var Group = Util.Group;
var CONTAINER_CLASS = 'g2-legend';
var TITLE_CLASS = 'g2-legend-title';
var LIST_CLASS = 'g2-legend-list';
var ITEM_CLASS = 'g2-legend-list-item';
var TEXT_CLASS = 'g2-legend-text';
var MARKER_CLASS = 'g2-legend-marker'; // find a dom node from the chidren of the node with className.
function findNodeByClass(node, className) {
return node.getElementsByClassName(className)[0];
}
function getParentNode(node, className) {
var nodeClass = node.className;
if (Util.isNil(nodeClass)) {
return node;
}
nodeClass = nodeClass.split(' ');
if (nodeClass.indexOf(className) > -1) {
return node;
}
if (node.parentNode) {
if (node.parentNode.className === CONTAINER_CLASS) {
return node.parentNode;
}
return getParentNode(node.parentNode, className);
}
return null;
}
function findItem(items, refer) {
var rst = null;
var value = refer instanceof Group ? refer.get('value') : refer;
Util.each(items, function (item) {
if (item.value === value) {
rst = item;
return false;
}
});
return rst;
}
var CatHtml = /*#__PURE__*/function (_Category) {
_inheritsLoose(CatHtml, _Category);
var _super = _createSuper(CatHtml);
function CatHtml() {
return _Category.apply(this, arguments) || this;
}
var _proto = CatHtml.prototype;
_proto.getDefaultCfg = function getDefaultCfg() {
var cfg = _Category.prototype.getDefaultCfg.call(this);
return Util.mix({}, cfg, {
/**
* type 标识
* @type {String}
*/
type: 'category-legend',
/**
* html 容器
* @type {DOM}
*/
container: null,
/**
* 使用html时的外层模板
* @type {String}
*/
containerTpl: '<div class="' + CONTAINER_CLASS + '">' + '<h4 class="' + TITLE_CLASS + '"></h4>' + '<ul class="' + LIST_CLASS + '"></ul>' + '</div>',
/**
* html 模板
* @type {String|Function}
*/
itemTpl: '<li class="' + ITEM_CLASS + ' item-{index} {checked}" data-color="{originColor}" data-value="{originValue}">' + '<i class="' + MARKER_CLASS + '" style="background-color:{color};"></i>' + '<span class="' + TEXT_CLASS + '">{value}</span></li>',
/**
* html style
* @type {Attrs}
*/
legendStyle: {},
/**
* 图例文字样式
* @type {ATTRS}
*/
textStyle: {
fill: '#333',
fontSize: 12,
textAlign: 'middle',
textBaseline: 'top',
fontFamily: FONT_FAMILY
},
/**
* 当文本太长时是否进行缩略
* @type {Boolean}
*/
abridgeText: false,
/**
* abridgeText true 鼠标放置在 item 上时显示全称的悬浮 div html 模板
* @type {String}
*/
tipTpl: '<div class="textTip"></div>',
/**
* abridgeText true 鼠标放置在 item 上时显示全称的悬浮 div 的样式
* @type {Attrs}
*/
tipStyle: {
display: 'none',
fontSize: '12px',
backgroundColor: '#fff',
position: 'absolute',
width: 'auto',
height: 'auto',
padding: '3px',
boxShadow: '2px 2px 5px #888'
},
/**
* useHtml true 时生效用于自动定位
* @type {[type]}
*/
autoPosition: true
});
};
_proto._init = function _init() {
return;
};
_proto.beforeRender = function beforeRender() {
return;
};
_proto.render = function render() {
this._renderHTML();
} // user interaction
;
_proto._bindEvents = function _bindEvents() {
var _this = this;
var legendWrapper = this.get('legendWrapper');
var itemListDom = findNodeByClass(legendWrapper, LIST_CLASS);
if (this.get('hoverable')) {
itemListDom.onmousemove = function (ev) {
return _this._onMousemove(ev);
};
itemListDom.onmouseout = function (ev) {
return _this._onMouseleave(ev);
};
}
if (this.get('clickable')) {
itemListDom.onclick = function (ev) {
return _this._onClick(ev);
};
}
} // mouse move listener of an item
// when mouse over an item, reduce the opacity of the other items.
;
_proto._onMousemove = function _onMousemove(ev) {
var items = this.get('items');
var target = ev.target;
var targetClass = target.className;
targetClass = targetClass.split(' ');
if (targetClass.indexOf(CONTAINER_CLASS) > -1 || targetClass.indexOf(LIST_CLASS) > -1) {
return;
}
var parentDom = getParentNode(target, ITEM_CLASS);
var hoveredItem = findItem(items, parentDom.getAttribute('data-value'));
if (hoveredItem) {
// change the opacity of other items
this.deactivate();
this.activate(parentDom.getAttribute('data-value'));
this.emit('itemhover', {
item: hoveredItem,
currentTarget: parentDom,
checked: hoveredItem.checked
});
} else if (!hoveredItem) {
// restore the opacity of all the items
this.deactivate();
this.emit('itemunhover', ev);
}
return;
} // mouse leave listener of an item
;
_proto._onMouseleave = function _onMouseleave(ev) {
// restore the opacity of all the items when mouse leave
this.deactivate();
this.emit('itemunhover', ev);
return;
} // the click listener of an item
;
_proto._onClick = function _onClick(ev) {
var _this2 = this;
var legendWrapper = this.get('legendWrapper');
var itemListDom = findNodeByClass(legendWrapper, LIST_CLASS);
var unCheckedColor = this.get('unCheckColor');
var items = this.get('items');
var mode = this.get('selectedMode');
var childNodes = itemListDom.childNodes;
var target = ev.target;
var targetClass = target.className;
targetClass = targetClass.split(' ');
if (targetClass.indexOf(CONTAINER_CLASS) > -1 || targetClass.indexOf(LIST_CLASS) > -1) {
return;
}
var parentDom = getParentNode(target, ITEM_CLASS);
var textDom = findNodeByClass(parentDom, TEXT_CLASS);
var markerDom = findNodeByClass(parentDom, MARKER_CLASS);
var clickedItem = findItem(items, parentDom.getAttribute('data-value'));
if (!clickedItem) {
return;
}
var domClass = parentDom.className;
var originColor = parentDom.getAttribute('data-color');
if (mode === 'single') {
// 单选模式
// update checked status
clickedItem.checked = true; // 其他图例项全部置灰
Util.each(childNodes, function (child) {
if (child !== parentDom) {
var childMarkerDom = findNodeByClass(child, MARKER_CLASS);
childMarkerDom.style.backgroundColor = unCheckedColor;
child.className = child.className.replace('checked', 'unChecked');
child.style.color = unCheckedColor;
var childItem = findItem(items, child.getAttribute('data-value'));
childItem.checked = false;
} else {
if (textDom) {
textDom.style.color = _this2.get('textStyle').fill;
}
if (markerDom) {
markerDom.style.backgroundColor = originColor;
}
parentDom.className = domClass.replace('unChecked', 'checked');
}
});
} else {
// 混合模式
var clickedItemChecked = domClass.indexOf('checked') !== -1; // domClass.includes('checked');
var count = 0;
Util.each(childNodes, function (child) {
if (child.className.indexOf('checked') !== -1) {
// .includes('checked')
count++;
}
});
if (!this.get('allowAllCanceled') && clickedItemChecked && count === 1) {
this.emit('clicklastitem', {
item: clickedItem,
currentTarget: parentDom,
checked: mode === 'single' ? true : clickedItem.checked
});
return;
} // 在判断最后一个图例后再更新checked状态防止点击最后一个图例item时图例样式没有变化但是checked状态改变了 fix #422
clickedItem.checked = !clickedItem.checked;
if (clickedItemChecked) {
if (markerDom) {
markerDom.style.backgroundColor = unCheckedColor;
}
parentDom.className = domClass.replace('checked', 'unChecked');
parentDom.style.color = unCheckedColor;
} else {
if (markerDom) {
markerDom.style.backgroundColor = originColor;
}
parentDom.className = domClass.replace('unChecked', 'checked');
parentDom.style.color = this.get('textStyle').fill;
}
}
this.emit('itemclick', {
item: clickedItem,
currentTarget: parentDom,
checked: mode === 'single' ? true : clickedItem.checked
});
return;
} // activate an item by reduce the opacity of other items.
// it is reserved for bi-direction interaction between charts / graph and legend
;
_proto.activate = function activate(value) {
var _this3 = this;
var self = this;
var items = self.get('items');
var item = findItem(items, value);
var legendWrapper = self.get('legendWrapper');
var itemListDom = findNodeByClass(legendWrapper, LIST_CLASS);
var childNodes = itemListDom.childNodes;
childNodes.forEach(function (child) {
var childMarkerDom = findNodeByClass(child, MARKER_CLASS);
var childItem = findItem(items, child.getAttribute('data-value'));
if (_this3.get('highlight')) {
if (childItem === item && childItem.checked) {
childMarkerDom.style.border = '1px solid #333';
return;
}
} else {
if (childItem === item) {
childMarkerDom.style.opacity = self.get('activeOpacity');
} else {
if (childItem.checked) childMarkerDom.style.opacity = self.get('inactiveOpacity');
}
} // if (childItem !== item && childItem.checked) {
// if (this.get('highlight')) {
// childMarkerDom.style.border = '1px solid #fff';
// } else childMarkerDom.style.opacity = 0.5;
// } else {
// if (this.get('highlight')) {
// childMarkerDom.style.border = '1px solid #333';
// } else childMarkerDom.style.opacity = 1;
// }
});
return;
} // restore the opacity of items
// it is reserved for bi-direction interaction between charts / graph and legend
;
_proto.deactivate = function deactivate() {
var _this4 = this;
var self = this;
var legendWrapper = self.get('legendWrapper');
var itemListDom = findNodeByClass(legendWrapper, LIST_CLASS);
var childNodes = itemListDom.childNodes;
childNodes.forEach(function (child) {
var childMarkerDom = findNodeByClass(child, MARKER_CLASS);
if (_this4.get('highlight')) {
childMarkerDom.style.border = '1px solid #fff';
} else {
childMarkerDom.style.opacity = self.get('inactiveOpacity');
}
});
return;
};
_proto._renderHTML = function _renderHTML() {
var _this5 = this;
// const canvas = this.get('canvas');
var container = this.get('container'); // const outterNode = container.parentNode;
var title = this.get('title');
var containerTpl = this.get('containerTpl');
var legendWrapper = DomUtil.createDom(containerTpl);
var titleDom = findNodeByClass(legendWrapper, TITLE_CLASS);
var itemListDom = findNodeByClass(legendWrapper, LIST_CLASS); // ul
var unCheckedColor = this.get('unCheckColor');
var LEGEND_STYLE = Util.deepMix({}, {
CONTAINER_CLASS: {
height: 'auto',
width: 'auto',
position: 'absolute',
overflowY: 'auto',
fontSize: '12px',
fontFamily: FONT_FAMILY,
lineHeight: '20px',
color: '#8C8C8C'
},
TITLE_CLASS: {
marginBottom: this.get('titleGap') + 'px',
fontSize: '12px',
color: '#333',
// 默认样式
textBaseline: 'middle',
fontFamily: FONT_FAMILY
},
LIST_CLASS: {
listStyleType: 'none',
margin: 0,
padding: 0,
textAlign: 'center'
},
LIST_ITEM_CLASS: {
cursor: 'pointer',
marginBottom: '5px',
marginRight: '24px'
},
MARKER_CLASS: {
width: '9px',
height: '9px',
borderRadius: '50%',
display: 'inline-block',
marginRight: '4px',
verticalAlign: 'middle'
}
}, this.get('legendStyle')); // fixIE 9 兼容问题,先加入 legendWrapper
// let container = this.get('container');
if (/^\#/.test(container) || typeof container === 'string' && container.constructor === String) {
// 如果传入 dom 节点的 id
var id = container.replace('#', '');
container = document.getElementById(id);
container.appendChild(legendWrapper);
} else {
var _position = this.get('position');
var rangeStyle = {};
if (_position === 'left' || _position === 'right') {
rangeStyle = {
maxHeight: (this.get('maxLength') || container.offsetHeight) + 'px'
};
} else {
rangeStyle = {
maxWidth: (this.get('maxLength') || container.offsetWidth) + 'px'
};
}
DomUtil.modifyCSS(legendWrapper, Util.mix({}, LEGEND_STYLE.CONTAINER_CLASS, rangeStyle, this.get(CONTAINER_CLASS)));
container.appendChild(legendWrapper);
}
DomUtil.modifyCSS(itemListDom, Util.mix({}, LEGEND_STYLE.LIST_CLASS, this.get(LIST_CLASS))); // render title
if (titleDom) {
if (title && title.text) {
titleDom.innerHTML = title.text;
DomUtil.modifyCSS(titleDom, Util.mix({}, LEGEND_STYLE.TITLE_CLASS, this.get(TITLE_CLASS), title));
} else {
legendWrapper.removeChild(titleDom);
}
} // 开始渲染图例项
var items = this.get('items');
var itemTpl = this.get('itemTpl');
var position = this.get('position');
var layout = this.get('layout');
var itemDisplay = position === 'right' || position === 'left' || layout === 'vertical' ? 'block' : 'inline-block';
var itemStyle = Util.mix({}, LEGEND_STYLE.LIST_ITEM_CLASS, {
display: itemDisplay
}, this.get(ITEM_CLASS));
var markerStyle = Util.mix({}, LEGEND_STYLE.MARKER_CLASS, this.get(MARKER_CLASS));
Util.each(items, function (item, index) {
var checked = item.checked;
var value = _this5._formatItemValue(item.value);
var markerColor = item.marker.fill || item.marker.stroke;
var color = checked ? markerColor : unCheckedColor;
var domStr;
if (Util.isFunction(itemTpl)) {
domStr = itemTpl(value, color, checked, index);
} else {
domStr = itemTpl;
}
var itemDiv = Util.substitute(domStr, Util.mix({}, item, {
index: index,
checked: checked ? 'checked' : 'unChecked',
value: value,
color: color,
originColor: markerColor,
// @2018-07-09 by blue.lb 修复如果legend值中存在双引号"时, 导致的无法点击触发legend正常操作bug
originValue: item.value.replace(/\"/g, '&quot;')
})); // li
var itemDom = DomUtil.createDom(itemDiv);
itemDom.style.color = _this5.get('textStyle').fill;
var markerDom = findNodeByClass(itemDom, MARKER_CLASS);
var textDom = findNodeByClass(itemDom, TEXT_CLASS);
DomUtil.modifyCSS(itemDom, itemStyle);
markerDom && DomUtil.modifyCSS(markerDom, markerStyle); // textDom && DomUtil.modifyCSS(textDom, this.get('textStyle'));
if (!checked) {
itemDom.style.color = unCheckedColor;
if (markerDom) {
markerDom.style.backgroundColor = unCheckedColor;
}
}
itemListDom.appendChild(itemDom); // abridge the text if the width of the text exceeds the width of the item
if (_this5.get('abridgeText')) {
var text = value; // const itemWidth = parseFloat(this.get(ITEM_CLASS).width.substr(0, this.get(ITEM_CLASS).width.length - 2));
var itemWidth = itemDom.offsetWidth;
var fs = _this5.get('textStyle').fontSize;
if (isNaN(fs)) {
// 6.5pt = 6.5 * 1/72 * 96 = 8.6px
if (fs.indexOf('pt') !== -1) fs = parseFloat(fs.substr(0, fs.length - 2)) * 1 / 72 * 96;else if (fs.indexOf('px') !== -1) fs = parseFloat(fs.substr(0, fs.length - 2));
}
var textWidth = fs * text.length;
var letterNum = Math.floor(itemWidth / fs);
if (itemWidth < 2 * fs) {
// unable to contain '...'
text = '';
} else if (itemWidth < textWidth) {
// replace the tail as '...
if (letterNum > 1) text = text.substr(0, letterNum - 1) + '...';
}
textDom.innerText = text; // show the text tip while mouse hovering an item
itemDom.addEventListener('mouseover', function () {
var tipDom = findNodeByClass(legendWrapper.parentNode, 'textTip');
tipDom.style.display = 'block';
tipDom.style.left = itemDom.offsetLeft + itemDom.offsetWidth + 'px';
tipDom.style.top = itemDom.offsetTop + 15 + 'px';
tipDom.innerText = value;
}); // hide the text tip while mouse leave the item
itemDom.addEventListener('mouseout', function () {
var tipDom = findNodeByClass(legendWrapper.parentNode, 'textTip');
tipDom.style.display = 'none';
});
}
}); // append the tip div as a brother node of legend dom
if (this.get('abridgeText')) {
var tipTpl = this.get('tipTpl');
var tipDom = DomUtil.createDom(tipTpl);
var tipDomStyle = this.get('tipStyle');
DomUtil.modifyCSS(tipDom, tipDomStyle);
legendWrapper.parentNode.appendChild(tipDom); // hide the tip while mouse entering the tip dom
tipDom.addEventListener('mouseover', function () {
tipDom.style.display = 'none';
});
}
this.set('legendWrapper', legendWrapper);
};
_proto._adjustPositionOffset = function _adjustPositionOffset() {
var autoPosition = this.get('autoPosition'); // @2018-12-29 by maplor. if autoPosition is false, don't set inline-style
if (autoPosition === false) {
return;
}
var position = this.get('position');
var offset = this.get('offset');
var offsetX = this.get('offsetX');
var offsetY = this.get('offsetY');
if (offsetX) offset[0] = offsetX;
if (offsetY) offset[1] = offsetY;
var legendWrapper = this.get('legendWrapper');
legendWrapper.style.left = position[0] + 'px';
legendWrapper.style.top = position[1] + 'px';
legendWrapper.style.marginLeft = offset[0] + 'px';
legendWrapper.style.marginTop = offset[1] + 'px';
};
_proto.getWidth = function getWidth() {
return DomUtil.getOuterWidth(this.get('legendWrapper'));
};
_proto.getHeight = function getHeight() {
return DomUtil.getOuterHeight(this.get('legendWrapper'));
};
_proto.move = function move(x, y) {
if (!/^\#/.test(this.get('container'))) {
DomUtil.modifyCSS(this.get('legendWrapper'), {
left: x + 'px',
top: y + 'px'
});
this.set('x', x);
this.set('y', y);
} else {
_Category.prototype.move.call(this, x, y);
}
};
_proto.destroy = function destroy() {
var legendWrapper = this.get('legendWrapper');
if (legendWrapper && legendWrapper.parentNode) {
legendWrapper.parentNode.removeChild(legendWrapper);
}
_Category.prototype.destroy.call(this);
};
return CatHtml;
}(Category);
module.exports = CatHtml;