@xiaomengqiang/charts
Version:
hcharts library for web visualization
284 lines (270 loc) • 10.4 kB
JavaScript
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
function _inheritsLoose(t, o) { t.prototype = Object.create(o.prototype), t.prototype.constructor = t, _setPrototypeOf(t, o); }
function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
import BaseChart from '../BaseChart/index.js';
import NodeManager from './NodeManager.js';
import LineManager from './LineManager.js';
import { initContainer } from './insert.js';
import { CHART_TYPE } from '../../util/constants.js';
/**
* Copyright (c) 2024 - present OpenTiny HUICharts Authors.
* Copyright (c) 2024 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
var FlowChart = /*#__PURE__*/function (_BaseChart) {
function FlowChart() {
var _this;
_this = _BaseChart.call(this) || this;
// 图表渲染容器
_this.dom = void 0;
// 图表所需数据
_this.data = void 0;
// 图表容器边距
_this.padding = 30;
// 图表最外层容器
_this.container = void 0;
// 图表svg元素容器
_this.svgContainer = void 0;
// 图表html元素容器
_this.htmlContainer = void 0;
// 图表容器的宽高变化监听器
_this.resizeObserver = null;
/**
* 拖拽中的节点
* node: 拖拽的节点
* nodePosn: 拖拽节点的尺寸信息
* initDisX, initDisY: 拖拽开始时mouse与node左上角的距离 + 父容器与屏幕距离
*/
_this.draggingNode = {
node: null,
nodePosn: null,
initDisX: 0,
initDisY: 0
};
/**
* 生成连线和计算位置
*/
_this.lineManager = void 0;
/**
* 生成节点和计算位置
*/
_this.nodeManager = void 0;
_this.dom = null;
_this.option = null;
_this.resizeObserver = null;
return _this;
}
// 初始化图表渲染容器
_inheritsLoose(FlowChart, _BaseChart);
var _proto = FlowChart.prototype;
_proto.init = function init(dom) {
this.dom = dom;
}
// 初始化图表渲染配置
;
_proto.setSimpleOption = function setSimpleOption(name, option) {
this.option = option;
}
// 图表渲染回调
;
_proto.render = function render() {
var _this2 = this;
initContainer(this.dom);
this.container = this.dom.getElementsByClassName('fc-container')[0];
this.svgContainer = this.dom.getElementsByClassName('fc-line-container')[0];
this.tagContainer = this.dom.getElementsByClassName('fc-tag-container')[0];
this.htmlContainer = this.dom.getElementsByClassName('fc-node-container')[0];
this.containerPosn = this.container.getBoundingClientRect();
this.resetContainerPosn();
this.createNodes();
this.createLines();
this.setResizeObserver();
setTimeout(function () {
_this2.svgContainer.setAttribute('style', "height:" + _this2.container.scrollHeight + "px");
}, 10);
}
// 图表渲染完成时回调
;
_proto.onRenderReady = function onRenderReady(callback) {
this.renderCallBack = callback;
}
// 图表刷新,刷新配置项
;
_proto.refresh = function refresh(option) {
this.option = option;
if (this.resizeObserver) {
this.resizeObserver.disconnect();
this.resizeObserver = null;
}
this.dom.innerHTML = '';
this.nodeManager = null;
this.lineManager = null;
this.render();
}
// 图表刷新,仅刷新数据
;
_proto.refreshData = function refreshData(data) {
this.option.data = data;
this.refresh(this.option);
}
// 刷新图表自适应宽度
;
_proto.setResize = function setResize() {
if (this.nodeManager && this.lineManager) {
this.containerPosn = this.container.getBoundingClientRect();
this.nodeManager.layoutNodes(this.data, this.containerPosn);
this.lineManager.updateAllLine();
}
}
/**
* 1.创建和渲染节点
* 2.处理数据,并计算出节点位置
* 3.移动节点到指定位置
*/;
_proto.createNodes = function createNodes() {
var _this3 = this;
this.data = this.option.data;
this.nodeManager = new NodeManager(this.data, this.option, this.htmlContainer);
// 此时节点已经渲染在dom上,可以获取到宽高,计算布局
setTimeout(function () {
_this3.nodeManager.layoutNodes(_this3.data, _this3.containerPosn);
}, 0);
}
/**
* 由于要支持前端框架,框架在渲染node时是异步的
* 因此,绘制线条时需要在微任务全部处理完成才行吗,使用 setTimeout(()=>{},0)
*/;
_proto.createLines = function createLines() {
var _this4 = this;
setTimeout(function () {
var gContainer = _this4.svgContainer.getElementsByClassName('fc-line-g')[0];
_this4.lineManager = new LineManager(_this4.data, gContainer, _this4.tagContainer, _this4.containerPosn, _this4.option);
// if(this.option.slient !== true){
// this.initEvent();
// }
_this4.renderCallBack && _this4.renderCallBack(_this4);
}, 10);
}
// 绑定事件
;
_proto.initEvent = function initEvent() {
var _this5 = this;
// 鼠标按下节点,后续如果情况复杂,可能改为绑定在document上
this.htmlContainer.childNodes.forEach(function (item, index) {
item.onmousedown = function (mousedownEvent) {
// 鼠标按下时刷新containerPosn,防止页面滚动后,containerPosn未刷新的现象
_this5.containerPosn = _this5.container.getBoundingClientRect();
// 鼠标点击
item.style.zIndex = 2;
var itemPosn = item.getBoundingClientRect();
_this5.draggingNode.node = item;
_this5.draggingNode.nodePosn = itemPosn;
_this5.draggingNode.initDisX = mousedownEvent.clientX - itemPosn.left + _this5.containerPosn.left;
_this5.draggingNode.initDisY = mousedownEvent.clientY - itemPosn.top + _this5.containerPosn.top;
};
});
// 鼠标移动
document.onmousemove = function (mousemoveEvent) {
if (_this5.draggingNode.node) {
// requestAnimationFrame(() => {
var moveX = mousemoveEvent.clientX - _this5.draggingNode.initDisX;
var moveY = mousemoveEvent.clientY - _this5.draggingNode.initDisY;
// 边界处理
if (moveX <= 0) {
moveX = 0;
}
if (moveX + _this5.draggingNode.nodePosn.width >= _this5.containerPosn.width) {
moveX = _this5.containerPosn.width - _this5.draggingNode.nodePosn.width;
}
if (moveY <= 0) {
moveY = 0;
}
if (moveY + _this5.draggingNode.nodePosn.height >= _this5.container.scrollHeight) {
moveY = _this5.container.scrollHeight - _this5.draggingNode.nodePosn.height;
}
// 设置定位
_this5.draggingNode.node.style.left = moveX + 'px';
_this5.draggingNode.node.style.top = moveY + 'px';
// 更改节点和连线的位置
var domId = _this5.draggingNode.node.id;
_this5.nodeManager.updateNode(domId, moveX, moveY);
_this5.lineManager.updateLine(domId);
}
};
// 鼠标抬起
document.onmouseup = function (e) {
if (_this5.draggingNode.node) {
_this5.draggingNode.node.style.zIndex = 1;
_this5.draggingNode = {
initDisX: 0,
initDisY: 0,
node: null,
nodePosn: null
};
}
};
document.onmouseleave = function (e) {
if (_this5.draggingNode.node) {
_this5.draggingNode.node.style.zIndex = 1;
_this5.draggingNode = {
node: null,
nodePosn: null,
initDisX: 0,
initDisY: 0
};
}
};
}
// 监听容器样式变化
;
_proto.setResizeObserver = function setResizeObserver() {
var _this6 = this;
this.resizeObserver = new ResizeObserver(function (entries) {
// TODO: 补充节流函数
if (_this6.nodeManager && _this6.lineManager) {
_this6.containerPosn = _this6.container.getBoundingClientRect();
_this6.resetContainerPosn();
_this6.nodeManager.layoutNodes(_this6.data, _this6.containerPosn);
_this6.lineManager.updateAllLine();
}
});
this.resizeObserver.observe(this.dom);
};
_proto.resetContainerPosn = function resetContainerPosn() {
var transformOption = getComputedStyle(this.dom)['transform'];
var scaleX = 1;
var scaleY = 1;
if (transformOption !== 'none') {
var transfromStr = transformOption.replace('matrix(', '').split(',');
scaleX = Number(transfromStr[0]);
scaleY = Number(transfromStr[3]);
}
this.containerPosn = _extends({}, this.containerPosn, {
width: this.containerPosn.width / scaleX,
height: this.containerPosn.height / scaleY,
scaleX: scaleX,
scaleY: scaleY
});
}
// 销毁图表
;
_proto.destory = function destory() {
this.resizeObserver.disconnect();
this.dom.innerHTML = '';
};
_proto.uninstall = function uninstall() {
this.destory();
};
return FlowChart;
}(BaseChart);
_defineProperty(FlowChart, "name", CHART_TYPE.FLOW);
export { FlowChart as default };