UNPKG

fastlion-amis

Version:

一种MIS页面生成工具

591 lines (590 loc) 31.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ChartRenderer = exports.Chart = void 0; var tslib_1 = require("tslib"); var react_1 = (0, tslib_1.__importDefault)(require("react")); var factory_1 = require("../factory"); var service_1 = require("../store/service"); var tpl_1 = require("../utils/tpl"); var classnames_1 = (0, tslib_1.__importDefault)(require("classnames")); var LazyComponent_1 = (0, tslib_1.__importDefault)(require("../components/LazyComponent")); var resize_sensor_1 = require("../utils/resize-sensor"); var tpl_builtin_1 = require("../utils/tpl-builtin"); var api_1 = require("../utils/api"); var Scoped_1 = require("../Scoped"); var helper_1 = require("../utils/helper"); var mobx_state_tree_1 = require("mobx-state-tree"); // Jay var empty_1 = (0, tslib_1.__importDefault)(require("antd/lib/empty")); var utils_1 = require("../utils/utils"); var EVAL_CACHE = {}; /** * ECharts 中有些配置项可以写函数,但 JSON 中无法支持,为了实现这个功能,需要将看起来像函数的字符串转成函数类型 * 目前 ECharts 中可能有函数的配置项有如下:interval、formatter、color、min、max、labelFormatter、pageFormatter、optionToContent、contentToOption、animationDelay、animationDurationUpdate、animationDelayUpdate、animationDuration、position、sort * 其中用得最多的是 formatter、sort,所以目前先只支持它们 * @param config ECharts 配置 */ function recoverFunctionType(config) { ['formatter', 'sort', 'renderItem', 'symbolSize', 'valueFormatter'].forEach(function (key) { var objects = (0, helper_1.findObjectsWithKey)(config, key); for (var _i = 0, objects_1 = objects; _i < objects_1.length; _i++) { var object = objects_1[_i]; var code = object[key]; if (typeof code === 'string' && code.trim().startsWith('function')) { try { if (!(code in EVAL_CACHE)) { EVAL_CACHE[code] = eval('(' + code + ')'); } object[key] = EVAL_CACHE[code]; } catch (e) { console.warn(code, e); } } } }); } var Chart = /** @class */ (function (_super) { (0, tslib_1.__extends)(Chart, _super); function Chart(props) { var _this = _super.call(this, props) || this; _this.handleJump = function (body) { var _a; var store = _this.props.store; var types = (0, helper_1.isMobile)() ? 'drawer' : 'dialog'; var action = { type: "action", actionType: types, close: true }; action[types] = { title: body.linkTitle, type: types, size: (_a = body.linkSize) !== null && _a !== void 0 ? _a : 'lg', bodyClassName: "overflow-y-auto max-h-nestSide-" + types, className: "h-full", actions: [], overlay: (0, helper_1.isMobile)() ? false : true, body: { schemaApi: { "method": "get", "url": body.linkUrl }, type: "service" } }; store.setCurrentAction(action); types === 'dialog' ? store.openDialog(body.bodydata) : store.openDrawer(body.bodydata); }; _this.refFn = function (ref) { return (0, tslib_1.__awaiter)(_this, void 0, void 0, function () { var chartRef, _a, chartTheme, onChartWillMount, onChartUnMount, env, onChartMount, theme, darkTheme; var _this = this; return (0, tslib_1.__generator)(this, function (_b) { switch (_b.label) { case 0: this.chartContent = ref; // 记录表格体 chartRef = this.props.chartRef; _a = this.props, chartTheme = _a.chartTheme, onChartWillMount = _a.onChartWillMount, onChartUnMount = _a.onChartUnMount, env = _a.env; onChartMount = this.props.onChartMount; if (!ref) return [3 /*break*/, 5]; theme = 'default'; if (chartTheme) { echarts.registerTheme('custom', chartTheme); theme = 'custom'; } if (!onChartWillMount) return [3 /*break*/, 2]; return [4 /*yield*/, onChartWillMount(echarts)]; case 1: _b.sent(); _b.label = 2; case 2: if (!env.loadChartExtends) return [3 /*break*/, 4]; return [4 /*yield*/, env.loadChartExtends()]; case 3: _b.sent(); _b.label = 4; case 4: darkTheme = localStorage.getItem('g_user_skin'); if (darkTheme === 'dark') { theme = 'dark'; } this.echarts = echarts.init(ref, theme); if (typeof onChartMount === 'string') { onChartMount = new Function('chart', 'echarts'); } onChartMount === null || onChartMount === void 0 ? void 0 : onChartMount(this.echarts, echarts); this.unSensor = (0, resize_sensor_1.resizeSensor)(ref, function () { var _a; var width = ref.offsetWidth; var height = ref.offsetHeight; (_a = _this.echarts) === null || _a === void 0 ? void 0 : _a.resize({ width: width, height: height }); }); chartRef && chartRef(this.echarts); this.renderChart(); return [3 /*break*/, 6]; case 5: chartRef && chartRef(null); this.unSensor && this.unSensor(); if (this.echarts) { onChartUnMount === null || onChartUnMount === void 0 ? void 0 : onChartUnMount(this.echarts, window.echarts); this.echarts.dispose(); delete this.echarts; } _b.label = 6; case 6: this.ref = ref; return [2 /*return*/]; } }); }); }; _this.dataset = []; _this.refFn = _this.refFn.bind(_this); _this.reload = _this.reload.bind(_this); _this.handleClick = _this.handleClick.bind(_this); _this.handleExport = _this.handleExport.bind(_this); _this.handleDialogConfirm = _this.handleDialogConfirm.bind(_this); _this.handleDrawerConfirm = _this.handleDrawerConfirm.bind(_this); _this.baseModalConfirm = _this.baseModalConfirm.bind(_this); _this.handleDialogClose = _this.handleDialogClose.bind(_this); _this.handleDrawerClose = _this.handleDrawerClose.bind(_this); _this.mounted = true; _this.containerRef = react_1.default.createRef(); // this.cacheHeight = 0; _this.cacheStyle = {}; props.config && _this.renderChart(props.config); // Jay _this.state = { hasRender: false, canvasHigh: '100%', visible: false, errMsg: '', showEmpty: false }; return _this; } Chart.prototype.componentDidMount = function () { var _a, _b, _c, _d; var _e = this.props, api = _e.api, data = _e.data, initFetch = _e.initFetch, source = _e.source; // 初始化的时候,默认将外部Panel的loading 给关闭 (_b = (_a = this.props).setPanelLoading) === null || _b === void 0 ? void 0 : _b.call(_a, false); if (source && (0, tpl_builtin_1.isPureVariable)(source)) { var ret = (0, tpl_builtin_1.resolveVariableAndFilter)(source, data, '| raw'); ret && this.renderChart(ret); } else if (api && initFetch !== false) { // Jay (_d = (_c = this.props).setPanelLoading) === null || _d === void 0 ? void 0 : _d.call(_c, true); this.reload(); } }; Chart.prototype.componentDidUpdate = function (prevProps) { var props = this.props; if ((0, api_1.isApiOutdated)(prevProps.api, props.api, prevProps.data, props.data)) { this.reload(); } else if (props.source && (0, tpl_builtin_1.isPureVariable)(props.source)) { var prevRet = prevProps.source ? (0, tpl_builtin_1.resolveVariableAndFilter)(prevProps.source, prevProps.data, '| raw') : null; var ret = (0, tpl_builtin_1.resolveVariableAndFilter)(props.source, props.data, '| raw'); if (prevRet !== ret) { this.renderChart(ret || {}); } } else if (props.config !== prevProps.config) { this.renderChart(props.config || {}); } else if (props.config && props.trackExpression && (0, tpl_1.filter)(props.trackExpression, props.data) !== (0, tpl_1.filter)(prevProps.trackExpression, prevProps.data)) { this.renderChart(props.config || {}); } }; Chart.prototype.componentWillUnmount = function () { this.mounted = false; clearTimeout(this.timer); }; Chart.prototype.handleExport = function (_a) { var _b, _c, _d, _e, _f; var api = _a.api; return (0, tslib_1.__awaiter)(this, void 0, void 0, function () { var res, baseUrl, link; return (0, tslib_1.__generator)(this, function (_g) { switch (_g.label) { case 0: return [4 /*yield*/, this.props.env.fetcher(api)]; case 1: res = _g.sent(); if (res.ok && res.data != null) { baseUrl = (_f = ((_e = (_d = (_c = (_b = this.props.env) === null || _b === void 0 ? void 0 : _b.axiosInstance) === null || _c === void 0 ? void 0 : _c.defaults) === null || _d === void 0 ? void 0 : _d.baseURL) !== null && _e !== void 0 ? _e : res === null || res === void 0 ? void 0 : res.reqUrl)) !== null && _f !== void 0 ? _f : ''; link = document.createElement('a'); link.href = baseUrl + res.data.fileUrl; link.download = res.data.fileName; document.body.appendChild(link); link.click(); document.body.removeChild(link); } return [2 /*return*/]; } }); }); }; Chart.prototype.handleClick = function (ctx) { var _a, _b; var _c = this.props, onAction = _c.onAction, data = _c.data; if (this.series && this.series.length > 0) { var clickAction = (_a = this.series[ctx.seriesIndex]) === null || _a === void 0 ? void 0 : _a.clickAction; if (clickAction) { onAction && onAction(null, clickAction, (0, helper_1.createObject)(data, ctx.data)); if (clickAction === null || clickAction === void 0 ? void 0 : clickAction.linkId) { var dataObj = (0, helper_1.createObject)(data, this.dataset[ctx.dataIndex]); (0, utils_1.linkJump)((_b = clickAction === null || clickAction === void 0 ? void 0 : clickAction.linkId) !== null && _b !== void 0 ? _b : '', dataObj) && (0, utils_1.ModleHandleClick)((0, tslib_1.__assign)((0, tslib_1.__assign)((0, tslib_1.__assign)({}, this.props), clickAction), { value: ctx.value, data: dataObj, handleJump: this.handleJump })); } } } }; Chart.prototype.reload = function (subpath, query) { var _this = this; var _a, _b, _c, _d; var _e = this.props, api = _e.api, env = _e.env, store = _e.store, interval = _e.interval, __ = _e.translate; if (query) { return this.receive(query); } else if (!env || !env.fetcher || !(0, api_1.isEffectiveApi)(api, store.data)) { return; } clearTimeout(this.timer); if (this.reloadCancel) { this.reloadCancel(); delete this.reloadCancel; (_a = this.echarts) === null || _a === void 0 ? void 0 : _a.hideLoading(); } (_b = this.echarts) === null || _b === void 0 ? void 0 : _b.showLoading(); // 请求Chart数据的时候,关闭Panel的loading (_d = (_c = this.props).setPanelLoading) === null || _d === void 0 ? void 0 : _d.call(_c, false); // Jay store.markFetching(true); env .fetcher(api, store.data, { cancelExecutor: function (executor) { return (_this.reloadCancel = executor); } }) .then(function (result) { var _a; // this.props.setPanelLoading?.(false) // Jay (0, mobx_state_tree_1.isAlive)(store) && store.markFetching(false); if (!result.ok) { _this.renderChart({}); // 将后端返回的错误渲染到空数据中 _this.setState({ errMsg: result.msg }); return env.notify('error', result.msg || __('fetchFailed'), result.msgTimeout !== undefined ? { closeButton: true, timeout: result.msgTimeout } : undefined); } delete _this.reloadCancel; var data = (0, api_1.normalizeApiResponseData)(result.data); if (data.series) { _this.series = data.series; } _this.setState({ errMsg: '', showEmpty: result.data == null }); // 说明返回的是数据接口。 if (!data.series && _this.props.config) { var ctx = (0, helper_1.createObject)(_this.props.data, data); _this.renderChart(_this.props.config, ctx); } else { _this.renderChart(result.data || {}); } (_a = _this.echarts) === null || _a === void 0 ? void 0 : _a.hideLoading(); interval && _this.mounted && (_this.timer = setTimeout(_this.reload, Math.max(interval, 1000))); }) .catch(function (reason) { var _a; // this.props.setPanelLoading?.(false) // Jay if (env.isCancel(reason)) { return; } (0, mobx_state_tree_1.isAlive)(store) && store.markFetching(false); env.notify('error', reason); (_a = _this.echarts) === null || _a === void 0 ? void 0 : _a.hideLoading(); }); }; Chart.prototype.receive = function (data) { var store = this.props.store; store.updateData(data); this.reload(); }; Chart.prototype.renderChart = function (config, data) { var _this = this; var _a, _b, _c, _d, _e, _f, _g; config && (this.pending = config); data && (this.pendingCtx = data); if (!this.echarts) { return; } var store = this.props.store; var onDataFilter = this.props.onDataFilter; var dataFilter = this.props.dataFilter; if (!onDataFilter && typeof dataFilter === 'string') { onDataFilter = new Function('config', 'echarts', 'data', dataFilter); } config = config || this.pending; data = data || this.pendingCtx || this.props.data; if (!(config === null || config === void 0 ? void 0 : config.dataset)) { config = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, config), { dataset: { source: [] } }); } if (typeof config === 'string') { config = new Function('return ' + config)(); } try { onDataFilter && (config = onDataFilter(config, window.echarts, data) || config); } catch (e) { console.warn(e); } if (config) { try { if (!this.props.disableDataMapping) { config = (0, tpl_builtin_1.dataMapping)(config, data, function (key, value) { return typeof value === 'function' || (typeof value === 'string' && value.startsWith('function')); }); } if ((_b = (_a = config.toolbox) === null || _a === void 0 ? void 0 : _a.feature) === null || _b === void 0 ? void 0 : _b.myExport) { config.toolbox.feature.myExport.icon = "path://M997.910386 1023.826532H25.812065C11.622368 1023.826532 0 1012.204164 0 997.99712V25.933493C0 11.726449 11.622368 0.104081 25.812065 0.104081c14.207044 0 25.829412 11.622368 25.829412 25.829412v946.234215h946.268909c14.207044 0 25.829412 11.622368 25.829412 25.829412 0 14.207044-11.622368 25.829412-25.829412 25.829412z m-117.52469-448.050956v292.710203c0 14.207044-11.622368 25.829412-25.829412 25.829411-14.189697 0-25.812065-11.622368-25.812065-25.829411V575.775576c0-14.207044 11.622368-25.829412 25.812065-25.829412 14.207044 0 25.829412 11.622368 25.829412 25.829412zM650.054649 463.853907c14.207044 0 25.812065 11.622368 25.812065 25.829412v378.80246c0 14.207044-11.605021 25.829412-25.812065 25.829411-14.189697 0-25.812065-11.622368-25.812065-25.829411V489.683319c0-14.207044 11.622368-25.829412 25.812065-25.829412z m-182.766072-77.470888v482.10276c0 14.207044-11.622368 25.829412-25.812065 25.829411-14.207044 0-25.829412-11.622368-25.829411-25.829411V386.383019c0-14.207044 11.622368-25.829412 25.829411-25.829412 14.189697 0 25.812065 11.622368 25.812065 25.829412z m-232.360624 163.563145c14.189697 0 25.812065 11.622368 25.812065 25.829412v292.710203c0 14.207044-11.622368 25.829412-25.812065 25.829411-14.207044 0-25.812065-11.622368-25.812065-25.829411V575.775576c0-14.207044 11.605021-25.829412 25.812065-25.829412z m418.405245-290.229608c-6.86934 5.585675-15.681523 6.557097-23.609019 4.19793-4.458132 0.884688-9.072386 1.040809-13.634599-0.607139l-207.589368-75.077027-162.192746 93.083024a25.864105 25.864105 0 0 1-34.554861-11.761143 25.881452 25.881452 0 0 1 11.761142-34.572207l171.941658-98.686047c7.545866-3.729566 15.907032-2.983653 22.915146 0.589792l214.424015 77.540276 226.54944-97.95748a25.898799 25.898799 0 0 1 36.324236 3.781606 25.916146 25.916146 0 0 1-3.764259 36.324236l-238.570785 103.144179z"; config.toolbox.feature.myExport.onclick = function () { _this.handleExport(config.toolbox.feature.myExport); }; } var chartObj = (_c = config.series) === null || _c === void 0 ? void 0 : _c[0]; if (chartObj) { this.dataset = chartObj.type === 'scatter' ? chartObj.data.map(function (item) { var jumpData = item[item.length - 1]; if (typeof jumpData == 'object') return jumpData; return {}; }) : (((_d = chartObj.data) === null || _d === void 0 ? void 0 : _d.length) > 0 ? chartObj.data : config.dataset.source); } recoverFunctionType(config); if ((0, mobx_state_tree_1.isAlive)(store) && store.loading) { (_e = this.echarts) === null || _e === void 0 ? void 0 : _e.showLoading(); } else { (_f = this.echarts) === null || _f === void 0 ? void 0 : _f.hideLoading(); } this.setState({ hasRender: true }); // Jay // 强制重绘 this.echarts.clear(); if (this.props.maskImageUrl) { var maskImage = new Image(); maskImage.src = this.props.maskImageUrl; config = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, config), { maskImage: maskImage }); } (_g = this.echarts) === null || _g === void 0 ? void 0 : _g.setOption(config, this.props.replaceChartOption); this.echarts.on('click', this.handleClick); } catch (e) { console.warn(e); } } }; Chart.prototype.handleDialogConfirm = function (values, action, ctx, components) { return (0, tslib_1.__awaiter)(this, void 0, void 0, function () { return (0, tslib_1.__generator)(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.baseModalConfirm('dialog')(values, action, ctx, components)]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }; Chart.prototype.handleDrawerConfirm = function (values, action, ctx, components) { return (0, tslib_1.__awaiter)(this, void 0, void 0, function () { return (0, tslib_1.__generator)(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.baseModalConfirm('drawer')(values, action, ctx, components)]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }; Chart.prototype.baseModalConfirm = function (type) { var _this = this; return function (values, action, ctx, components) { return (0, tslib_1.__awaiter)(_this, void 0, void 0, function () { var _a, store, pageField, stopAutoRefreshWhenModalIsOpen, interval, silentPolling, env; return (0, tslib_1.__generator)(this, function (_b) { _a = this.props, store = _a.store, pageField = _a.pageField, stopAutoRefreshWhenModalIsOpen = _a.stopAutoRefreshWhenModalIsOpen, interval = _a.interval, silentPolling = _a.silentPolling, env = _a.env; switch (type) { case 'drawer': default: store.closeDrawer(true); break; case 'dialog': store.closeDialog(true); break; } return [2 /*return*/]; }); }); }; }; Chart.prototype.handleDialogClose = function (confirmed, formInstance) { return this.handleBaseModalClose('dialog')(confirmed, formInstance); }; Chart.prototype.handleDrawerClose = function (confirmed, formInstance) { return this.handleBaseModalClose('drawer')(confirmed, formInstance); }; Chart.prototype.handleBaseModalClose = function (type) { var _this = this; return function (confirmed, formInstance) { var _a = _this.props, __ = _a.translate, store = _a.store; switch (type) { case 'dialog': store.closeDialog(); break; case 'drawer': store.closeDrawer(); break; } }; }; Chart.prototype.handleLoopGetParentHeight = function (currentDom) { var _a; var closetParent = (_a = currentDom.parentElement) !== null && _a !== void 0 ? _a : {}; var clientHeight = closetParent.clientHeight, clientWidth = closetParent.clientWidth; if (clientHeight) { // 防止滚动条影响 return { height: Number.parseInt(Number(clientHeight - 2).toString()), width: "calc(" + clientWidth + " - 1px)" }; } else { return this.handleLoopGetParentHeight(closetParent); } }; Chart.prototype.getDomStyle = function () { var _a; var style = this.props.style || {}; var _b = this.props, height = _b.height, width = _b.width, ns = _b.classPrefix; // requestAnimationFrame(() => { // if (!height && this.containerRef.current) { // if (this.cacheHeight) { // style.height = this.cacheHeight; // } else { // const parentDomHeight = this.handleLoopGetParentHeight(this.containerRef.current); // this.cacheHeight = parentDomHeight; // style.height = parentDomHeight; // } // } // return style; // }) if (!height && this.containerRef.current) { if ((_a = this.cacheStyle) === null || _a === void 0 ? void 0 : _a.height) { style.height = this.cacheStyle.height; } else { var _c = this.handleLoopGetParentHeight(this.containerRef.current), parentDomHeight = _c.height, parentDomWidth = _c.width; // const gridHeight = domUtils.closest(this.containerRef, `${ns}Grid`)?.clientHeight; // if (parentDomHeight) { // } // this.cacheHeight = parentDomHeight; style.height = parentDomHeight; style.width = parentDomWidth; } } else { style.height = height; } style.width = width || style.width; this.cacheStyle = style; return style; }; Chart.prototype.render = function () { var _this = this; var _a = this.props, className = _a.className, width = _a.width, height = _a.height, ns = _a.classPrefix, unMountOnHidden = _a.unMountOnHidden, render = _a.render, store = _a.store; var style = this.props.style || {}; width && (style.width = width); height && (style.height = height); // 新增未配置高度的情况下,自动获取父/祖先 容器高度 // requestAnimationFrame(() => { // if (!height && this.containerRef.current) { // if (this.cacheHeight) { // style.height = this.cacheHeight; // } else { // const parentDomHeight = this.handleLoopGetParentHeight(this.containerRef.current); // this.cacheHeight = parentDomHeight; // style.height = parentDomHeight; // } // } // }) return (react_1.default.createElement("div", { className: (0, classnames_1.default)(ns + "Chart", className), ref: this.containerRef, style: (0, tslib_1.__assign)({}, this.cacheStyle) }, react_1.default.createElement(LazyComponent_1.default, { unMountOnHidden: unMountOnHidden, placeholder: "..." // 之前那个 spinner 会导致 sensor 失效 , component: function () { var _a; return (react_1.default.createElement(react_1.default.Fragment, null, !_this.state.showEmpty && react_1.default.createElement("div", { className: ns + "Chart-content", ref: _this.refFn, style: (0, tslib_1.__assign)({}, (_this.getDomStyle())) }), (!_this.state.hasRender || _this.state.showEmpty) && react_1.default.createElement("div", { style: { display: 'flex', justifyContent: 'center', alignItems: 'center', width: '100%', height: '100%', minHeight: 300, whiteSpace: 'normal' } }, react_1.default.createElement(empty_1.default, { description: ((_a = _this.state.errMsg) === null || _a === void 0 ? void 0 : _a.length) ? _this.state.errMsg : (_this.props.translate(_this.props.placeholder || 'placeholder.noData')) })))); } }), this.props.store.dialogOpen ? render('dialog', (0, tslib_1.__assign)((0, tslib_1.__assign)({}, (store.action && store.action.dialog)), { type: 'dialog' }), { key: 'dialog', data: store.dialogData, onConfirm: this.handleDialogConfirm, onClose: this.handleDialogClose, show: store.dialogOpen, replace: store.replace }) : null, this.props.store.drawerOpen ? render('drawer', (0, tslib_1.__assign)((0, tslib_1.__assign)({}, (store.action && store.action.drawer)), { type: 'drawer' }), { key: 'drawer', data: store.drawerData, onConfirm: this.handleDrawerConfirm, onClose: this.handleDrawerClose, show: store.drawerOpen, // onAction: this.handleAction, }) : null)); }; Chart.defaultProps = { replaceChartOption: false, unMountOnHidden: false }; Chart.propsList = []; return Chart; }(react_1.default.Component)); exports.Chart = Chart; var ChartRenderer = /** @class */ (function (_super) { (0, tslib_1.__extends)(ChartRenderer, _super); function ChartRenderer(props, context) { var _this = _super.call(this, props) || this; var scoped = context; scoped.registerComponent(_this); return _this; } ChartRenderer.prototype.componentWillUnmount = function () { _super.prototype.componentWillUnmount.call(this); var scoped = this.context; scoped.unRegisterComponent(this); }; var _a; ChartRenderer.contextType = Scoped_1.ScopedContext; ChartRenderer = (0, tslib_1.__decorate)([ (0, factory_1.Renderer)({ type: 'chart', storeType: service_1.ServiceStore.name }), (0, tslib_1.__metadata)("design:paramtypes", [Object, typeof (_a = typeof Scoped_1.IScopedContext !== "undefined" && Scoped_1.IScopedContext) === "function" ? _a : Object]) ], ChartRenderer); return ChartRenderer; }(Chart)); exports.ChartRenderer = ChartRenderer; //# sourceMappingURL=./renderers/Chart.js.map