From 6857a138d7ee3f2eb57ee15a9d44f4fe965190df Mon Sep 17 00:00:00 2001 From: king <18310653075@163.com> Date: 星期一, 15 五月 2023 17:56:57 +0800 Subject: [PATCH] 2023-05-15 --- src/menu/components/chart/antv-X6/chartcompile/formconfig.jsx | 356 ++++++++++ src/menu/components/chart/antv-X6/chartcompile/index.jsx | 179 +++++ src/menu/components/chart/antv-X6/chartcompile/index.scss | 6 src/menu/components/chart/antv-X6/index.scss | 68 + src/menu/components/chart/antv-X6/index.jsx | 1449 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 2,058 insertions(+), 0 deletions(-) diff --git a/src/menu/components/chart/antv-X6/chartcompile/formconfig.jsx b/src/menu/components/chart/antv-X6/chartcompile/formconfig.jsx new file mode 100644 index 0000000..9eed12a --- /dev/null +++ b/src/menu/components/chart/antv-X6/chartcompile/formconfig.jsx @@ -0,0 +1,356 @@ +/** + * @description 鑾峰彇鍥捐〃瑙嗗浘閰嶇疆琛ㄥ崟 + * @param {object} card // 鍥捐〃瀵硅薄 + */ +export function getBaseForm (card, columns) { + let appType = sessionStorage.getItem('appType') + let roleList = sessionStorage.getItem('sysRoles') + if (roleList) { + try { + roleList = JSON.parse(roleList) + } catch (e) { + roleList = [] + } + } else { + roleList = [] + } + + let menulist = [] + + if (appType === 'pc') { + menulist = sessionStorage.getItem('appMenus') + if (menulist) { + try { + menulist = JSON.parse(menulist) + } catch (e) { + menulist = [] + } + } else { + menulist = [] + } + } else if (appType === '') { + menulist = sessionStorage.getItem('fstMenuList') + if (menulist) { + try { + menulist = JSON.parse(menulist) + } catch (e) { + menulist = [] + } + } else { + menulist = [] + } + } + + return [ + { + type: 'text', + field: 'title', + label: '鏍囬', + initval: card.title, + required: false + }, + { + type: 'text', + field: 'name', + label: '缁勪欢鍚嶇О', + initval: card.name, + tooltip: '鐢ㄤ簬缁勪欢闂寸殑鍖哄垎銆�', + required: true + }, + { + type: 'number', + field: 'width', + label: '瀹藉害', + initval: card.width, + tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��', + min: 1, + max: 24, + decimal: 0, + required: true + }, + { + type: 'styleInput', + field: 'height', + label: '鍥捐〃楂樺害', + initval: card.height, + tooltip: '鍥捐〃缁樺浘鍖哄煙鐨勯珮搴︼紝涓嶅寘鎷爣棰樺強鍐呭杈硅窛銆�', + required: true, + options: ['px', 'vh', 'vw'] + }, + { + type: 'radio', + field: 'permission', + label: '鏉冮檺楠岃瘉', + initval: card.permission || 'false', + required: false, + options: [ + {value: 'true', label: '鍚敤'}, + {value: 'false', label: '绂佺敤'}, + ], + forbid: !appType || sessionStorage.getItem('editMenuType') === 'popview' + }, + { + type: 'multiselect', + field: 'blacklist', + label: '榛戝悕鍗�', + initval: card.blacklist || [], + required: false, + options: roleList, + forbid: !!appType + }, + { + type: 'radio', + field: 'click', + label: '鐐瑰嚮浜嬩欢', + initval: card.click || '', + tooltip: '鐐瑰嚮鑺傜偣鏃惰Е鍙戠殑浜嬩欢銆�', + required: false, + options: [ + {value: '', label: '鏁版嵁鍒囨崲'}, + {value: 'menu', label: '鑿滃崟'}, + {value: 'menus', label: '鑿滃崟缁�'} + ], + controlFields: [ + {field: 'menu', values: ['menu']}, + {field: 'menus', values: ['menus']}, + {field: 'menuType', values: ['menus']}, + {field: 'open', values: ['menu', 'menus']}, + {field: 'joint', values: ['menu', 'menus']}, + ] + }, + { + type: appType === '' ? 'cascader' : 'select', + field: 'menu', + label: '鍏宠仈鑿滃崟', + initval: card.menu || (appType === '' ? [] : ''), + required: true, + extendName: 'MenuNo', + options: menulist + }, + { + type: 'select', + field: 'menuType', + label: '鑿滃崟绫诲瀷', + initval: card.menuType || '', + required: true, + options: columns + }, + { + type: 'radio', + field: 'open', + label: '鎵撳紑鏂瑰紡', + initval: card.open || 'blank', + required: false, + options: [ + {value: 'blank', label: '鏂扮獥鍙�'}, + {value: 'self', label: '褰撳墠绐楀彛'}, + ], + forbid: appType !== 'pc' + }, + { + type: 'radio', + field: 'joint', + label: '鍙傛暟鎷兼帴', + initval: card.joint || 'true', + required: false, + options: [ + {value: 'true', label: '鏄�'}, + {value: 'false', label: '鍚�'}, + ], + }, + { + type: 'table', + field: 'menus', + label: '鑿滃崟缁�', + initval: card.menus || [], + required: true, + span: 24, + actions: appType === 'pc' ? ['view'] : [], + columns: [ + { + title: '鏍囪瘑', + dataIndex: 'sign', + inputType: 'input', + editable: true, + unique: true, + required: false, + width: '35%' + }, + { + title: '鑿滃崟', + dataIndex: 'menu', + inputType: !appType ? 'cascader' : 'select', + editable: true, + required: true, + extends: !appType ? 'Menu' : [{key: 'label', value: 'label'}], + width: '35%', + render: (text, record) => record.label, + options: menulist + } + ] + } + ] +} + +/** + * @description 鑾峰彇鍥捐〃瑙嗗浘閰嶇疆琛ㄥ崟 + * @param {object} card // 鍥捐〃瀵硅薄 + * @param {Array} columns // 鏄剧ず鍒� + */ +export function getOptionForm (card, columns) { + return [ + { + type: 'select', + field: 'subtype', + label: '绫诲瀷', + initval: card.subtype || 'mindmap', + required: true, + options: [{ + value: 'mindmap', + label: '鎬濈淮瀵煎浘' + }, { + value: 'indentTree', + label: '缂╄繘鏂囦欢鏍�' + }, { + value: 'kapmap', + label: '鐭ヨ瘑鍥捐氨鏍�' + }], + controlFields: [ + {field: 'dirField', values: ['mindmap']}, + {field: 'nodeColor', values: ['mindmap']}, + // {field: 'collapsed', values: ['indentTree', 'kapmap']}, + ] + }, + { + type: 'radio', + field: 'rootType', + label: '鏍硅妭鐐瑰彇鍊�', + initval: card.rootType || 'fixed', + tooltip: '閫夋嫨涓婄骇鏃讹紝璇峰~鍐欐牴鑺傜偣鐨勬枃鏈拰鍊肩殑瀛楁鍚�', + required: true, + options: [{ + value: 'fixed', + label: '鍥哄畾鍊�' + }, { + value: 'supvalue', + label: '涓婄骇缁勪欢' + }, { + value: 'line', + label: '琛�' + }], + controlFields: [ + {field: 'rootLabel', values: ['fixed', 'supvalue']}, + {field: 'rootValue', values: ['fixed', 'supvalue']}, + {field: 'mark', values: ['line']}, + ] + }, + { + type: 'text', + field: 'rootValue', + label: '鏍硅妭鐐瑰��', + initval: card.rootValue || '', + required: true + }, + { + type: 'text', + field: 'rootLabel', + label: '鏍硅妭鐐规枃鏈�', + initval: card.rootLabel || '', + required: true + }, + { + type: 'select', + field: 'valueField', + label: '鍊煎瓧娈�', + initval: card.valueField || '', + required: true, + options: columns + }, + { + type: 'select', + field: 'labelField', + label: '鏂囨湰瀛楁', + initval: card.labelField || '', + required: true, + options: columns + }, + { + type: 'select', + field: 'parentField', + label: '涓婄骇瀛楁', + initval: card.parentField || '', + required: true, + options: columns + }, + { + type: 'text', + field: 'mark', + label: '椤剁骇鏍囪瘑', + initval: card.mark || '', + tooltip: '涓婄骇瀛楁鍊间笌椤剁骇鏍囪瘑鐩稿悓鏃讹紝瑙嗕负鏍硅妭鐐广��', + required: true + }, + { + type: 'select', + field: 'dirField', + label: '鏂瑰悜鎺у埗', + initval: card.dirField || '', + required: false, + options: columns, + controlFields: [ + {field: 'dirSign', notNull: true}, + {field: 'leftColor', notNull: true}, + ] + }, + { + type: 'text', + field: 'dirSign', + label: '宸﹀悜鏍囪', + initval: card.dirSign || '', + tooltip: '褰撹妭鐐瑰�间笌鏍囪鐩稿悓鏃惰妭鐐逛俊鎭綅浜庤妭鐐瑰乏渚э紝澶氫釜鍊艰鐢ㄩ�楀彿鍒嗛殧銆�', + required: false + }, + { + type: 'color', + field: 'nodeColor', + label: '鑺傜偣棰滆壊', + initval: card.nodeColor || '#1890ff', + tooltip: '鍙充晶鑺傜偣鐨勬爣璁伴鑹层��', + colorType: 'hex', + required: false + }, + { + type: 'color', + field: 'leftColor', + label: '宸﹁妭鐐归鑹�', + initval: card.leftColor || '#26C281', + tooltip: '宸︿晶鑺傜偣鐨勬爣璁伴鑹层��', + colorType: 'hex', + required: false + }, + { + type: 'radio', + field: 'empty', + label: '绌哄�奸殣钘�', + initval: card.empty || 'show', + tooltip: '褰撴煡璇㈡暟鎹负绌烘椂锛岄殣钘忚缁勪欢銆�', + required: false, + options: [ + {value: 'show', label: '鍚�'}, + {value: 'hidden', label: '鏄�'}, + ], + }, + { + type: 'radio', + field: 'collapsed', + label: '鑺傜偣鍚堝苟', + initval: card.collapsed || 'false', + tooltip: '涓�绾ц妭鐐规槸鍚﹀悎骞躲��', + required: false, + options: [ + {value: 'false', label: '鍚�'}, + {value: 'true', label: '鏄�'}, + ], + }, + ] +} diff --git a/src/menu/components/chart/antv-X6/chartcompile/index.jsx b/src/menu/components/chart/antv-X6/chartcompile/index.jsx new file mode 100644 index 0000000..4396a49 --- /dev/null +++ b/src/menu/components/chart/antv-X6/chartcompile/index.jsx @@ -0,0 +1,179 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { fromJS } from 'immutable' +import { Modal, Form, Tabs } from 'antd' +import { EditOutlined } from '@ant-design/icons' + +import { getBaseForm, getOptionForm } from './formconfig' +import asyncComponent from '@/utils/asyncComponent' +import './index.scss' + +const { TabPane } = Tabs +const NormalForm = asyncComponent(() => import('@/components/normalform/modalform')) + +class LineChartDrawerForm extends Component { + static propTpyes = { + plot: PropTypes.object, + config: PropTypes.object, + plotchange: PropTypes.func + } + + state = { + view: 'normal', + visible: false, + plot: null, + formlist: null, + baseFormlist: null + } + + showDrawer = () => { + const { config } = this.props + + this.setState({ + visible: true, + view: 'normal', + plot: fromJS(config.plot).toJS(), + baseFormlist: getBaseForm(config.plot, config.columns), + formlist: getOptionForm(config.plot, config.columns) + }) + } + + onSubmit = () => { + const { config } = this.props + const { plot, view } = this.state + + if (view === 'normal') { + this.norRef.handleConfirm().then(res => { + let _plot = {...plot, ...res} + + if (_plot.click !== 'menus') { + delete _plot.menus + } + if (_plot.click !== 'menu') { + delete _plot.menu + delete _plot.MenuID + delete _plot.MenuName + delete _plot.MenuNo + delete _plot.tabType + } else if (sessionStorage.getItem('appType') === '' && _plot.menu) { + let list = null + try { + list = JSON.parse(sessionStorage.getItem('thdMenuList')) || [] + } catch (e) { + list = [] + } + + let id = _plot.menu[_plot.menu.length - 1] + + list.forEach(item => { + if (item.MenuID === id) { + _plot.MenuID = id + _plot.MenuName = item.MenuName + _plot.MenuNo = item.MenuNo + _plot.tabType = item.type + } + }) + } + + this.setState({ + plot: _plot, + visible: false + }) + + this.props.plotchange({...config, plot: _plot}) + }) + } else if (view === 'base') { + this.baseRef.handleConfirm().then(res => { + let _plot = {...plot, ...res} + + if (_plot.click !== 'menus') { + delete _plot.menus + } + if (_plot.click !== 'menu') { + delete _plot.menu + delete _plot.MenuID + delete _plot.MenuName + delete _plot.MenuNo + delete _plot.tabType + } else if (sessionStorage.getItem('appType') === '' && _plot.menu) { + let list = null + try { + list = JSON.parse(sessionStorage.getItem('thdMenuList')) || [] + } catch (e) { + list = [] + } + + let id = _plot.menu[_plot.menu.length - 1] + + list.forEach(item => { + if (item.MenuID === id) { + _plot.MenuID = id + _plot.MenuName = item.MenuName + _plot.MenuNo = item.MenuNo + _plot.tabType = item.type + } + }) + } + + this.setState({ + plot: _plot, + visible: false + }) + + this.props.plotchange({...config, plot: _plot}) + }) + } + } + + changeTab = (tab) => { + const { plot, view } = this.state + + if (view === 'normal') { + this.norRef.handleConfirm().then(res => { + this.setState({ + plot: {...plot, ...res}, + view: tab + }) + }) + } else if (view === 'base') { + this.baseRef.handleConfirm().then(res => { + this.setState({ + plot: {...plot, ...res}, + view: tab + }) + }) + } + } + + render() { + const { config } = this.props + const { view, visible, baseFormlist, formlist } = this.state + + return ( + <div className="line-chart-drawer-form"> + <EditOutlined title="缂栬緫" onClick={this.showDrawer} /> + <Modal + wrapClassName="mk-pop-modal" + visible={visible} + width={850} + maskClosable={false} + onOk={this.onSubmit} + onCancel={() => { this.setState({ visible: false }) }} + destroyOnClose + > + {config.name ? <div className="mk-com-name">{config.name} - 缂栬緫</div> : null} + <Tabs activeKey={view} onChange={this.changeTab}> + <TabPane tab="缁勪欢璁剧疆" key="base"> + <NormalForm formlist={baseFormlist} inputSubmit={this.onSubmit} wrappedComponentRef={(inst) => this.baseRef = inst}/> + </TabPane> + <TabPane tab="鍥捐〃璁剧疆" key="normal"> + <NormalForm formlist={formlist} inputSubmit={this.onSubmit} wrappedComponentRef={(inst) => this.norRef = inst}/> + </TabPane> + </Tabs> + </Modal> + </div> + ); + } +} + +export default Form.create()(LineChartDrawerForm) \ No newline at end of file diff --git a/src/menu/components/chart/antv-X6/chartcompile/index.scss b/src/menu/components/chart/antv-X6/chartcompile/index.scss new file mode 100644 index 0000000..19ce53c --- /dev/null +++ b/src/menu/components/chart/antv-X6/chartcompile/index.scss @@ -0,0 +1,6 @@ +.line-chart-drawer-form { + display: inline-block; + > .anticon-edit { + color: #1890ff; + } +} diff --git a/src/menu/components/chart/antv-X6/index.jsx b/src/menu/components/chart/antv-X6/index.jsx new file mode 100644 index 0000000..985a6f5 --- /dev/null +++ b/src/menu/components/chart/antv-X6/index.jsx @@ -0,0 +1,1449 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { is, fromJS } from 'immutable' +import { Popover, message } from 'antd' +import { ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons' +import G6 from '@antv/g6' + +import MKEmitter from '@/utils/events.js' +import asyncComponent from '@/utils/asyncComponent' +import asyncIconComponent from '@/utils/asyncIconComponent' +import { resetStyle, getTables, getHeight, checkComponent } from '@/utils/utils-custom.js' +import './index.scss' + +const { Util } = G6 + +const SettingComponent = asyncIconComponent(() => import('@/menu/datasource')) +const ChartCompileForm = asyncIconComponent(() => import('./chartcompile')) +const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent')) +const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader')) +const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent')) + +const MindData = [ + 'Modeling Methods', + [ + 'Classification', + ['Logistic regression', 'Linear discriminant analysis', 'Rules', 'Decision trees', 'Naive Bayes', 'K nearest neighbor', 'Probabilistic neural network', 'Support vector machine'] + ], + [ + 'Consensus', + [ + 'Models diversity', + ['Different initializations', 'Different parameter choices', 'Different architectures', 'Different modeling methods', 'Different training sets', 'Different feature sets'] + ], + [ + 'Methods', + ['Classifier selection', 'Classifier fusion'] + ], + [ + 'Common', + ['Bagging', 'Boosting', 'AdaBoost'] + ] + ], + [ + 'Regression', + ['Multiple linear regression', 'Partial least squares', 'Multi-layer feedforward neural network', 'General regression neural network', 'Support vector regression'] + ] +] + +const styles = { + blue: '#1890ff', + red: '#f5222d', + orange_red: '#fa541c', + orange: '#fa8c16', + orange_yellow: '#faad14', + yellow: '#fadb14', + yellow_green: '#a0d911', + green: '#52c41a', + cyan: '#13c2c2', + blue_purple: '#2f54eb', + purple: '#722ed1', + magenta: '#eb2f96', + grass_green: '#aeb303', + deep_red: '#c32539', + deep_blue: '#1d3661' +} + +let systemColor = '#1890ff' +if (window.GLOB.style) { + let type = window.GLOB.style.replace(/bg_black_style_|bg_white_style_/, '') + systemColor = styles[type] || '#1890ff' +} +const COLORS = ['#5B8FF9', '#F6BD16', '#5AD8A6', '#945FB9', '#E86452', '#6DC8EC', '#FF99C3', '#1E9493', '#FF9845', '#5D7092'] + +// 鎬濈淮瀵煎浘 +G6.registerNode( + 'dice-mind-map-root', { + jsx: (cfg) => { + const width = Util.getTextSize(cfg.label, 16)[0] + 24 + + return ` + <group> + <rect style={{width: ${width}, height: 42, stroke: ${systemColor}, radius: 4}} keyshape> + <text style={{ fontSize: 16, marginLeft: 6, marginTop: 12 }}>${cfg.label}</text> + </rect> + </group> + ` + }, + getAnchorPoints() { + return [ + [0, 0.5], + [1, 0.5] + ] + } + }, + 'single-node', +) + +G6.registerNode( + 'dice-mind-map-leaf', { + jsx: (cfg) => { + const width = Util.getTextSize(cfg.label, 12)[0] + 24 + + return ` + <group> + <rect style={{width: ${width}, height: 26, fill: 'transparent', cursor: pointer }}> + <text style={{ fontSize: 12, fill: ${cfg.selected ? systemColor : '#000000'}, marginLeft: 12, marginTop: 6, cursor: pointer }}>${cfg.label}</text> + </rect> + <rect style={{ fill: ${cfg.color}, width: ${width}, height: 2, x: 0, y: 32, cursor: pointer }} /> + </group> + ` + }, + getAnchorPoints() { + return [ + [0, 0.965], + [1, 0.965] + ] + } + }, + 'single-node', +) +G6.registerBehavior('dice-mindmap', { + getEvents() { + return { + 'node:click': 'editNode', + 'canvas:click': 'onCanvasClick' + } + }, + editNode(evt) { + const item = evt.item + const model = item.get('model') + + this.graph.getNodes().forEach(node => { + let _model = node.get('model') + if (_model.selected) { + _model.selected = false + this.graph.updateItem(node, _model, false) + } + }) + + model.selected = true + this.graph.updateItem(item, model, false) + }, + onCanvasClick(e) { + this.graph.getNodes().forEach(node => { + let _model = node.get('model') + if (_model.selected) { + _model.selected = false + this.graph.updateItem(node, _model, false) + } + }) + } +}) +G6.registerBehavior('scroll-canvas', { + getEvents: function getEvents() { + return { + wheel: 'onWheel' + } + }, + onWheel: function onWheel(ev) { + const { graph } = this + if (!graph) { + return + } + if (ev.ctrlKey) { + const canvas = graph.get('canvas') + const point = canvas.getPointByClient(ev.clientX, ev.clientY) + let ratio = graph.getZoom() + if (ev.wheelDelta > 0) { + ratio += ratio * 0.05 + } else { + ratio *= ratio * 0.05 + } + graph.zoomTo(ratio, { + x: point.x, + y: point.y + }) + } else { + const x = ev.deltaX || ev.movementX + const y = ev.deltaY || ev.movementY || (-ev.wheelDelta * 125) / 3 + graph.translate(-x, -y) + } + ev.preventDefault() + } +}) + +// 缂╄繘鏂囦欢鏍� +G6.registerNode('indentedRoot', { + draw(model, group) { + const keyShape = group.addShape('rect', { + attrs: { + x: -46, + y: -16, + width: 92, + height: 32, + fill: systemColor, + radius: 2, + stroke: '#5B8FF9', + lineWidth: 0 + }, + name: 'key-shape' + }) + + const text = group.addShape('text', { + attrs: { + text: model.label || 'root', + fill: "#fff", + fontSize: 12, + x: 0, + y: 0, + textAlign: 'center', + textBaseline: 'middle' + }, + name: 'root-text-shape' + }) + const textBBox = text.getBBox() + const width = textBBox.width + 24 + const height = textBBox.height + 12 + keyShape.attr({ + x: -width / 2, + y: -height / 2, + width, + height + }) + + return keyShape + }, + getAnchorPoints() { + return [ + [0.5, 1] + ] + }, + update: undefined +}) + +G6.registerNode('indentedNode', { + addChildCount(group, tag, props) { + const { collapsed, branchColor, count } = props + let clickCircleY = 10 + // 瀛愮被鏁伴噺 icon锛岀粯鍒跺渾鐐瑰湪鑺傜偣姝d笅鏂� + if (tag) { + const childCountGroup = group.addGroup({ + name: 'child-count-group' + }) + childCountGroup.setMatrix([1, 0, 0, 0, 1, 0, 0, clickCircleY, 1]) + const countBackWidth = collapsed ? 26 : 12 + childCountGroup.addShape('rect', { + attrs: { + width: countBackWidth, + height: 12, + radius: 6, + stroke: branchColor, + lineWidth: 2, + fill: collapsed ? branchColor : '#fff', + x: -countBackWidth / 2, + y: -6, + cursor: 'pointer', + }, + name: 'child-count-rect-shape' + }) + const childCountText = childCountGroup.addShape('text', { + attrs: { + text: count, + fill: '#fff', + x: 0, + y: 0, + fontSize: 10, + textAlign: 'center', + textBaseline: 'middle', + cursor: 'pointer', + }, + name: 'child-count-text-shape' + }) + const childHoverIcon = childCountGroup.addShape('path', { + attrs: { + stroke: '#fff', + lineWidth: 1, + cursor: 'pointer', + path: [['M', -3, 2], ['L', 0, -2], ['L', 3, 2]] + }, + name: 'child-count-expand-icon', + capture: false + }) + childHoverIcon.hide() + + // 杩炴帴 count 鐨勭嚎娈� + const countLink = group.addShape('path', { + attrs: { + path: [['M', 0, 0], ['L', 0, 11]], + stroke: branchColor, + lineWidth: 2, + }, + name: 'count-link' + }) + countLink.toBack() + + if (collapsed) { + childCountGroup.show() + childCountText.show() + countLink.show() + } + else { + childCountGroup.hide() + childCountText.hide() + countLink.hide() + } + + clickCircleY += 16 + } + }, + addBottomLine(group, props) { + const { x, width, stroke, lineWidth } = props + return group.addShape('path', { + attrs: { + path: [ + ['M', x - 1, 0], + ['L', width, 0], + ], + stroke, + lineWidth, + }, + name: 'node-path-shape' + }) + }, + addName(group, props) { + const { label, x = 0, y, fill } = props + return group.addShape('text', { + attrs: { + text: label, + x, + y, + textAlign: 'start', + textBaseline: 'top', + fill, + fontSize: 14, + fontFamily: 'PingFangSC-Regular', + cursor: 'pointer', + }, + name: 'not-root-text-shape' + }) + }, + draw(model, group) { + const { collapsed, depth, label, children, selected } = model + // 鏄惁涓烘牴鑺傜偣 + const rootNode = depth === 0 + // 瀛愯妭鐐规暟閲� + const childCount = children ? children.length : 0 + + let width = 0 + const height = 24 + const x = 0 + const y = -height / 2 + const borderRadius = 4 + // 鍚嶇О鏂囨湰 + const text = this.addName(group, { label, x, y }) + + let textWidth = text.getBBox().width + width = textWidth + 20 + + const keyShapeAttrs = { + x, + y, + width, + height, + radius: borderRadius, + fill: undefined, + stroke: undefined, + } + + const keyShape = group.addShape('rect', { + attrs: keyShapeAttrs, + name: 'root-key-shape-rect-shape' + }) + + // 搴曢儴妯嚎 + const bottomLine = this.addBottomLine(group, { + stroke: model.branchColor || '#AAB7C4', + lineWidth: 3, + x, + width + }) + + let nameColor = 'rgba(0, 0, 0, 0.85)' + + if (selected) { + nameColor = systemColor + } + + // 鍚嶇О + text.attr({ + y: y - 12, + fill: nameColor + }) + text.toFront() + textWidth = text.getBBox().width + + if (bottomLine) bottomLine.toFront() + + this.addChildCount(group, childCount && !rootNode, { + collapsed, + branchColor: model.branchColor, + count: childCount ? `${childCount}` : undefined + }) + + const bbox = group.getBBox() + const backContainer = group.addShape('path', { + attrs: { + path: childCount ? [ + ['M', bbox.minX, bbox.minY], + ['L', bbox.maxX, bbox.minY], + ['L', bbox.maxX, bbox.maxY], + ['L', bbox.minX + 20, bbox.maxY], + ['L', bbox.minX + 20, bbox.maxY + 20], + ['L', bbox.minX, bbox.maxY + 20], + ['Z'] + ] : [ + ['M', bbox.minX, bbox.minY], + ['L', bbox.maxX, bbox.minY], + ['L', bbox.maxX, bbox.maxY], + ['L', bbox.minX, bbox.maxY], + ['Z'] + ], + fill: '#fff', + opacity: 0 + } + }) + backContainer.toBack() + return keyShape + } +}) + +G6.registerEdge('indentedEdge', { + afterDraw: (cfg, group) => { + const sourceNode = cfg.sourceNode && cfg.sourceNode.getModel() + const targetNode = cfg.targetNode && cfg.targetNode.getModel() + const color = sourceNode.branchColor || targetNode.branchColor || cfg.color || '#000' + + const keyShape = group.get('children')[0] + keyShape.attr({ + stroke: color, + lineWidth: 3 // branchThick + }) + group.toBack() + }, + getControlPoints: (cfg) => { + const startPoint = cfg.startPoint + const endPoint = cfg.endPoint + return [ + startPoint, + { + x: startPoint.x, + y: endPoint.y, + }, + endPoint + ] + }, + update: undefined +}, 'polyline') + +G6.registerBehavior('wheel-scroll', { + getDefaultCfg() { + return { + direction: 'y', + zoomKey: 'ctrl', + sensitivity: 3, + scalableRange: -64 + } + }, + getEvents() { + return { + wheel: 'onWheel' + } + }, + onWheel(ev) { + const graph = this.graph + let keyDown = ev[`${this.zoomKey}Key`] + if (this.zoomKey === 'control') keyDown = ev.ctrlKey + if (keyDown) { + const sensitivity = this.get('sensitivity') + const canvas = graph.get('canvas') + const point = canvas.getPointByClient(ev.clientX, ev.clientY) + let ratio = graph.getZoom() + if (ev.wheelDelta > 0) { + ratio *= (1 + 0.01 * sensitivity) + } else { + ratio *= (1 - 0.01 * sensitivity) + } + graph.zoomTo(ratio, { + x: point.x, + y: point.y + }) + graph.emit('wheelzoom', ev) + } else { + let dx = ev.deltaX || ev.movementX + let dy = ev.deltaY || ev.movementY + if (!dy && navigator.userAgent.indexOf('Firefox') > -1) dy = (-ev.wheelDelta * 125) / 3 + + const width = this.graph.get('width') + const height = this.graph.get('height') + const graphCanvasBBox = this.graph.get('group').getCanvasBBox() + + let expandWidth = this.scalableRange + let expandHeight = this.scalableRange + // 鑻� scalableRange 鏄� 0~1 鐨勫皬鏁帮紝鍒欎綔涓烘瘮渚嬭�冭檻 + if (expandWidth < 1 && expandWidth > -1) { + expandWidth = width * expandWidth + expandHeight = height * expandHeight + } + + const { minX, maxX, minY, maxY } = graphCanvasBBox + + if (dx > 0) { + if (maxX < -expandWidth) { + dx = 0 + } else if (maxX - dx < -expandWidth) { + dx = maxX + expandWidth + } + } else if (dx < 0) { + if (minX > width + expandWidth) { + dx = 0 + } else if (minX - dx > width + expandWidth) { + dx = minX - (width + expandWidth) + } + } + + if (dy > 0) { + if (maxY < -expandHeight) { + dy = 0 + } else if (maxY - dy < -expandHeight) { + dy = maxY + expandHeight + } + } else if (dy < 0) { + if (minY > height + expandHeight) { + dy = 0 + } else if (minY - dy > height + expandHeight) { + dy = minY - (height + expandHeight) + } + } + + if (this.get('direction') === 'x') { + dy = 0 + } else if (this.get('direction') === 'y') { + dx = 0 + } + + graph.translate(-dx, -dy) + } + ev.preventDefault() + } +}) +G6.registerBehavior('hover-node', { + getEvents() { + return { + 'node:mouseover': 'onNodeMouseOver', + 'node:mouseleave': 'onNodeMouseLeave', + 'node:mouseenter': 'onNodeMouseEnter' + } + }, + onNodeMouseEnter(ev) { + const { item } = ev + if (!item || item.get('destroyed')) return + item.toFront() + const model = item.getModel() + const { collapsed, depth } = model + const rootNode = depth === 0 || model.isRoot + const group = item.getContainer() + + if (rootNode) return + + // 鎺у埗瀛愯妭鐐逛釜鏁版爣璁� + if (!collapsed) { + const childCountGroup = group.find(e => e.get('name') === 'child-count-group') + if (childCountGroup) { + childCountGroup.show() + } + } + }, + onNodeMouseOver(ev) { + const shape = ev.target + + // tooltip鏄剧ず銆侀殣钘� + this.graph.emit('tooltip: show', ev) + + // expand 鐘舵�佷笅锛岃嫢 hover 鍒板瓙鑺傜偣涓暟鏍囪锛屽~鍏呰儗鏅�+鏄剧ず鏀惰捣 icon + const { item } = ev + const group = item.getContainer() + const model = item.getModel() + if (!model.collapsed) { + const childCountGroup = group.find(e => e.get('name') === 'child-count-group') + if (childCountGroup) { + childCountGroup.show() + const back = childCountGroup.find(e => e.get('name') === 'child-count-rect-shape') + const expandIcon = childCountGroup.find(e => e.get('name') === 'child-count-expand-icon') + const rootNode = model.depth === 0 || model.isRoot + const branchColor = rootNode ? '#576286' : model.branchColor + if (shape.get('parent').get('name') === 'child-count-group') { + if (back) { + back.attr('fill', branchColor || '#fff') + } + if (expandIcon) { + expandIcon.show() + } + } else { + if (back) { + back.attr('fill', '#fff') + } + if (expandIcon) { + expandIcon.hide() + } + } + } + } + }, + onNodeMouseLeave(ev) { + const { item } = ev + const model = item.getModel() + const group = item.getContainer() + const { collapsed } = model + + if (!collapsed) { + const childCountGroup = group.find(e => e.get('name') === 'child-count-group') + if (childCountGroup) { + childCountGroup.hide() + } + + const iconsLinkPath = group.find(e => e.get('name') === 'icons-link-path') + if (iconsLinkPath) { + iconsLinkPath.hide() + } + } + + this.graph.emit('tooltip: hide', ev) + } +}) +G6.registerBehavior('click-node', { + getEvents() { + return { + 'node:click': 'onNodeClick', + 'canvas:click': 'onCanvasClick' + } + }, + onNodeClick(e) { + const { item, target } = e + const shape = target + const shapeName = shape.cfg.name + let model = item.getModel() + + // 鐐瑰嚮鏀惰捣/灞曞紑 icon + if (shapeName === 'child-count-rect-shape' || shapeName === 'child-count-text-shape') { + const updatedCollapsed = !model.collapsed + this.graph.updateItem(item, { collapsed: updatedCollapsed }) + this.graph.layout() + return + } + + // 閫変腑鑺傜偣 + this.graph.getNodes().forEach(node => { + let _model = node.get('model') + if (_model.selected) { + _model.selected = false + this.graph.updateItem(node, _model, false) + } + }) + + model.selected = true + this.graph.updateItem(item, model, false) + + return + }, + onCanvasClick(e) { + this.graph.getNodes().forEach(node => { + let _model = node.get('model') + if (_model.selected) { + _model.selected = false + this.graph.updateItem(node, _model, false) + } + }) + } +}) +const dataIndTransform = (data) => { + const changeData = (d) => { + let data = { ...d } + + data.type = data.isRoot ? 'indentedRoot' : 'indentedNode' + + if (d.children) { + data.children = d.children.map((child) => changeData(child)) + } + // 缁欏畾 branchColor 鍜� 0-2 灞傝妭鐐� depth + if (data.children && data.children.length) { + data.depth = 0 + data.children.forEach((subtree, i) => { + subtree.branchColor = COLORS[i % COLORS.length] + // dfs + let currentDepth = 1 + subtree.depth = currentDepth + Util.traverseTree(subtree, child => { + child.branchColor = COLORS[i % COLORS.length] + + if (!child.depth) { + child.depth = currentDepth + 1 + } + else currentDepth = subtree.depth + if (child.children) { + child.children.forEach(subChild => { + subChild.depth = child.depth + 1 + }) + } + + if (!data.isRoot) { + child.collapsed = data.collapsed || false + } + return true + }) + }) + } + + return data + } + return changeData(data) +} + +// 鐭ヨ瘑鍥捐氨鏍� +G6.registerNode('treeNode', { + draw: (cfg, group) => { + const { label, selected, children, isRoot } = cfg + const rootNode = !!isRoot + const hasChildren = children && children.length !== 0 + + let width = 0 + const height = 28 + const x = 0 + const y = -height / 2 + + // 鍚嶇О鏂囨湰 + const text = group.addShape('text', { + attrs: { + text: label, + x: x * 2, + y, + textAlign: 'left', + textBaseline: 'top', + fontFamily: 'PingFangSC-Regular', + }, + cursor: 'pointer', + name: 'name-text-shape', + }) + const textWidth = text.getBBox().width + width = textWidth + 20 + + width = width < 60 ? 60 : width + + if (!rootNode && hasChildren) { + width += 22 + } + + const keyShapeAttrs = { + x, + y, + width, + height, + radius: 4 + } + + const keyShape = group.addShape('rect', { + attrs: keyShapeAttrs, + name: 'root-key-shape-rect-shape' + }) + + if (!rootNode) { + // 搴曢儴妯嚎 + group.addShape('path', { + attrs: { + path: [ + ['M', x - 1, 0], + ['L', width, 0], + ], + stroke: '#AAB7C4', + lineWidth: 1, + }, + name: 'node-path-shape' + }) + } + + const mainX = x - 10 + const mainY = -height + 15 + + if (rootNode) { + group.addShape('rect', { + attrs: { + x: mainX, + y: mainY, + width: width + 12, + height, + radius: 14, + fill: systemColor, + cursor: 'pointer', + }, + name: 'main-shape' + }) + } + + let nameColor = 'rgba(0, 0, 0, 0.85)' + if (selected) { + nameColor = systemColor + } + + // 鍚嶇О + if (rootNode) { + group.addShape('text', { + attrs: { + text: label, + x: mainX + 18, + y: 1, + textAlign: 'left', + textBaseline: 'middle', + fill: '#ffffff', + fontSize: 12, + fontFamily: 'PingFangSC-Regular', + cursor: 'pointer', + }, + name: 'root-text-shape' + }) + } else { + group.addShape('text', { + attrs: { + text: label, + x: mainX + 6, + y: y - 5, + textAlign: 'start', + textBaseline: 'top', + fill: nameColor, + fontSize: 12, + fontFamily: 'PingFangSC-Regular', + cursor: 'pointer', + }, + name: 'not-root-text-shape' + }) + } + + // 瀛愮被鏁伴噺 + if (hasChildren && !rootNode) { + const childCountHeight = 12 + const childCountX = width - 22 + const childCountY = -childCountHeight / 2 + + group.addShape('rect', { + attrs: { + width: 22, + height: 12, + stroke: systemColor, + fill: '#fff', + x: childCountX, + y: childCountY, + radius: 6, + cursor: 'pointer', + }, + name: 'child-count-rect-shape', + }) + group.addShape('text', { + attrs: { + text: `${children.length}`, + fill: 'rgba(0, 0, 0, .65)', + x: childCountX + 11, + y: childCountY + 12, + fontSize: 10, + width: 22, + textAlign: 'center', + cursor: 'pointer', + }, + name: 'child-count-text-shape' + }) + } + + return keyShape + } +}) + +G6.registerEdge('smooth', { + draw(cfg, group) { + const { startPoint, endPoint } = cfg + const hgap = Math.abs(endPoint.x - startPoint.x) + + const path = [ + ['M', startPoint.x, startPoint.y], + [ + 'C', + startPoint.x + hgap / 4, + startPoint.y, + endPoint.x - hgap / 2, + endPoint.y, + endPoint.x, + endPoint.y, + ], + ] + + const shape = group.addShape('path', { + attrs: { + stroke: '#AAB7C4', + path, + }, + name: 'smooth-path-shape', + }) + return shape + }, +}) + +G6.registerBehavior('click-item', { + getEvents() { + return { + 'node:click': 'onNodeClick', + 'canvas:click': 'onCanvasClick' + } + }, + onNodeClick(e) { + const { item } = e + let model = item.getModel() + + if (model.children) return + // 閫変腑鑺傜偣 + this.graph.getNodes().forEach(node => { + let _model = node.get('model') + if (_model.selected) { + _model.selected = false + this.graph.updateItem(node, _model, false) + } + }) + + model.selected = true + this.graph.updateItem(item, model, false) + + return + }, + onCanvasClick(e) { + this.graph.getNodes().forEach(node => { + let _model = node.get('model') + if (_model.selected) { + _model.selected = false + this.graph.updateItem(node, _model, false) + } + }) + } +}) + +class antvG6Chart extends Component { + static propTpyes = { + card: PropTypes.object, + updateConfig: PropTypes.func, + deletecomponent: PropTypes.func, + } + + state = { + card: null, + eventListener: null + } + + UNSAFE_componentWillMount () { + const { card } = this.props + + if (card.isNew) { + let _plot = { + width: card.width || 24, + height: 400, + subtype: card.subtype, + name: card.name + } + + let _card = { + uuid: card.uuid, + type: card.type, + format: 'array', // 缁勪欢灞炴�� - 鏁版嵁鏍煎紡 + pageable: false, // 缁勪欢灞炴�� - 鏄惁鍙垎椤� + switchable: true, // 缁勪欢灞炴�� - 鏁版嵁鏄惁鍙垏鎹� + width: _plot.width, + name: _plot.name, + subtype: card.subtype, + setting: { interType: 'system' }, + style: { + borderWidth: '1px', borderColor: 'rgb(217, 217, 217)', + marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px' + }, + headerStyle: { fontSize: '16px', borderBottomWidth: '1px', borderBottomColor: '#e8e8e8' }, + columns: [], + scripts: [], + search: [], + action: [], + plot: _plot, + } + + if (card.config) { + let config = fromJS(card.config).toJS() + + _card.plot = config.plot + _card.plot.name = card.name + _card.style = config.style + _card.headerStyle = config.headerStyle + + _card.setting = config.setting + _card.columns = config.columns + _card.scripts = config.scripts + } + + this.updateComponent(_card) + } else { + this.setState({ + card: fromJS(card).toJS() + }) + } + } + + componentDidMount () { + MKEmitter.addListener('tabsChange', this.handleTabsChange) + setTimeout(() => { + this.viewrender() + }, 1000) + } + + shouldComponentUpdate (nextProps, nextState) { + return !is(fromJS(this.state), fromJS(nextState)) + } + + /** + * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊锛屾竻闄ゅ揩鎹烽敭璁剧疆 + */ + componentWillUnmount () { + this.setState = () => { + return + } + MKEmitter.removeListener('tabsChange', this.handleTabsChange) + } + + handleTabsChange = (parentId) => { + const { card } = this.state + + if (parentId.indexOf(card.uuid) > -1 || parentId === 'all') { + let _element = document.getElementById(card.uuid + 'canvas') + if (_element) { + _element.innerHTML = '' + } + + this.$timer && clearTimeout(this.$timer) + this.$timer = setTimeout(this.viewrender, 100) + } + } + + getdata = () => { + const { card } = this.state + + const setData = (list) => { + let item = { + label: list[0], + id: list[0], + children: [] + } + if (!list[1]) { + delete item.children + + return item + } else if (!Array.isArray(list[1])) { + return list.map(m => ({label: m, id: m})) + } + + for (let i = 1; i < list.length; i++) { + let cell = setData(list[i]) + + if (Array.isArray(cell)) { + item.children.push(...cell) + } else { + item.children.push(cell) + } + } + + return item + } + + let data = setData(MindData) + + if (card.plot.subtype === 'mindmap') { + if (card.plot.dirField) { + data.children[0].direction = 'left' + data.children[2].direction = 'left' + } + + data.children.forEach(item => { + if (item.direction === 'left') { + item.color = card.plot.leftColor || '#26C281' + } else { + item.direction = 'right' + item.color = card.plot.nodeColor || '#1890ff' + } + }) + + data.collapsed = false + data.type = 'dice-mind-map-root' + + const collapse = (item) => { + if (!item.children) return + + item.children.forEach(cell => { + cell.collapsed = card.plot.collapsed === 'true' + cell.direction = cell.direction || 'right' + cell.type = 'dice-mind-map-leaf' + cell.color = cell.color || item.color + collapse(cell) + }) + } + + collapse(data) + } else if (card.plot.subtype === 'indentTree') { + data.isRoot = true + data.collapsed = false + + data.children.forEach(item => { + item.collapsed = card.plot.collapsed === 'true' + }) + } else if (card.plot.subtype === 'kapmap') { + data.isRoot = true + data.collapsed = false + + if (card.plot.collapsed === 'true') { + const collapse = (item) => { + if (!item.children) return + + item.children.forEach(cell => { + cell.collapsed = true + collapse(cell) + }) + } + + collapse(data) + } + } + + return data + } + + viewrender = () => { + const { card } = this.state + + if (card.plot.subtype === 'mindmap') { + this.ponitrender() + } else if (card.plot.subtype === 'indentTree') { + this.indentrender() + } else if (card.plot.subtype === 'kapmap') { + this.kapmaprender() + } + } + + kapmaprender = () => { + const { card } = this.state + const plot = card.plot + const data = this.getdata() + const height = getHeight(plot.height) + + const graph = new G6.TreeGraph({ + container: card.uuid + 'canvas', + width: this.wrap.scrollWidth - 30, + height: height, + modes: { + default: [ + { + type: 'collapse-expand', + }, + 'drag-canvas', + 'zoom-canvas', + 'click-item' + ], + }, + defaultNode: { + type: 'treeNode', + anchorPoints: [ + [0, 0.5], + [1, 0.5], + ], + }, + defaultEdge: { + type: 'smooth', + }, + layout: { + type: 'compactBox', + direction: 'LR', + getId: function getId(d) { + return d.id + }, + getHeight: function getHeight() { + return 16 + }, + getWidth: function getWidth(d) { + const labelWidth = G6.Util.getTextSize(d.label, 12)[0] + const width = 60 + labelWidth + return width + }, + getVGap: function getVGap() { + return 15 + }, + getHGap: function getHGap() { + return 30 + } + } + }) + + graph.data(data) + graph.render() + graph.fitView() + + if (plot.collapsed === 'true') { + graph.zoomTo(1, { x: 0, y: height / 2 }) + } + } + + indentrender = () => { + const { card } = this.state + const plot = card.plot + const data = this.getdata() + + const tree = new G6.TreeGraph({ + container: card.uuid + 'canvas', + width: this.wrap.scrollWidth - 30, + height: getHeight(plot.height), + layout: { + type: 'indented', + direction: 'LR', + isHorizontal: true, + indent: 40, + getHeight: (d) => { + if (d.isRoot) { + return 30 + } + if (d.collapsed && d.children && d.children.length) { + return 36 + } + return 22 + }, + getVGap: () => { + return 10 + }, + }, + defaultEdge: { + type: 'indentedEdge', + style: { + lineWidth: 2, + radius: 16 + } + }, + minZoom: 0.5, + modes: { + default: [ + 'drag-canvas', + 'wheel-scroll', + 'hover-node', + 'click-node' + ] + } + }) + + tree.on('afterrender', e => { + tree.getEdges().forEach(edge => { + const targetNode = edge.getTarget().getModel() + const color = targetNode.branchColor + tree.updateItem(edge, { color }) + }) + setTimeout(() => { + tree.moveTo(32, 32) + tree.zoomTo(0.7) + }, 16) + }) + + tree.data(dataIndTransform(data)) + + tree.render() + } + + /** + * @description 鏁g偣鍥� + */ + ponitrender = () => { + const { card } = this.state + const plot = card.plot + const data = this.getdata() + const width = this.wrap.scrollWidth - 30 + const height = getHeight(plot.height) + let modes = ['drag-canvas', 'zoom-canvas', 'dice-mindmap'] + + if (plot.collapsed === 'true') { + modes = [{ type: 'collapse-expand' },'drag-canvas', 'zoom-canvas', 'dice-mindmap'] + } + + const tree = new G6.TreeGraph({ + container: card.uuid + 'canvas', + width: width, + height: height, + fitView: true, + layout: { + type: 'mindmap', + direction: 'H', + getHeight: () => { + return 16 + }, + getWidth: (node) => { + return node.level === 0 ? + Util.getTextSize(node.label, 16)[0] + 12 : + Util.getTextSize(node.label, 12)[0] + }, + getVGap: () => { + return 10 + }, + getHGap: () => { + return 60 + }, + getSide: (node) => { + return node.data.direction + } + }, + defaultEdge: { + type: 'cubic-horizontal', + style: { + lineWidth: 2 + } + }, + minZoom: 0.5, + modes: { + default: modes + } + }) + + tree.data(data) + + tree.render() + + if (plot.collapsed === 'true' && plot.dirField) { + tree.zoomTo(1, { x: width / 2, y: height / 2 }) + } else if (plot.collapsed === 'true') { + tree.zoomTo(1, { x: 0, y: height / 2 }) + } + } + + updateComponent = (card) => { + if (this.state.card && (!is(fromJS(card.plot), fromJS(this.state.card.plot)) || !is(fromJS(card.style), fromJS(this.state.card.style)))) { + let _element = document.getElementById(card.uuid + 'canvas') + if (_element) { + _element.innerHTML = '' + } + this.$timer && clearTimeout(this.$timer) + this.$timer = setTimeout(() => { + this.viewrender() + }, 150) + } + + card.width = card.plot.width + card.name = card.plot.name + card.subtype = card.plot.subtype + + card.$c_ds = true + card.errors = checkComponent(card) + + if (card.errors.length === 0) { + card.$tables = getTables(card) + } + + if (!card.plot.valueField) { + card.errors.push({ level: 0, detail: '鍥捐〃淇℃伅灏氭湭璁剧疆锛�'}) + } else { + let columns = card.columns.map(c => c.field) + if (!columns.includes(card.plot.valueField)) { + card.errors.push({ level: 0, detail: '鍊煎瓧娈靛湪瀛楁闆嗕腑涓嶅瓨鍦�'}) + } else if (!columns.includes(card.plot.labelField)) { + card.errors.push({ level: 0, detail: '鏂囨湰瀛楁鍦ㄥ瓧娈甸泦涓笉瀛樺湪'}) + } else if (!columns.includes(card.plot.parentField)) { + card.errors.push({ level: 0, detail: '涓婄骇瀛楁鍦ㄥ瓧娈甸泦涓笉瀛樺湪'}) + } + } + + this.setState({ + card: card + }) + this.props.updateConfig(card) + } + + changeStyle = () => { + const { card } = this.state + + MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle) + } + + getStyle = (style) => { + let _card = {...this.state.card, style} + + this.updateComponent(_card) + } + + clickComponent = (e) => { + if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') { + e.stopPropagation() + MKEmitter.emit('clickComponent', this.state.card.uuid, null, (style) => { + let _card = {...this.state.card} + _card.style = {..._card.style, ...style} + + this.updateComponent(_card) + }) + } + } + + render() { + const { card } = this.state + let _style = resetStyle(card.style) + + return ( + <div className="menu-scatter-chart-edit-box" style={_style} onClick={this.clickComponent} id={card.uuid}> + <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ + <div className="mk-popover-control"> + <ChartCompileForm config={card} plotchange={this.updateComponent}/> + <CopyComponent type="antvG6" card={card}/> + <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/> + <UserComponent config={card}/> + <DeleteOutlined className="close" title="delete" onClick={() => this.props.deletecomponent(card.uuid)}/> + <SettingComponent config={card} updateConfig={this.updateComponent}/> + </div> + } trigger="hover"> + <ToolOutlined/> + </Popover> + <NormalHeader config={card} updateComponent={this.updateComponent}/> + <div className="canvas" style={{minHeight: card.plot.height}} id={card.uuid + 'canvas'} ref={ref => this.wrap = ref}></div> + <div className="component-name"> + <div className="center"> + <div className="title" onDoubleClick={() => { + let oInput = document.createElement('input') + oInput.value = 'anchor' + card.uuid + document.body.appendChild(oInput) + oInput.select() + document.execCommand('Copy') + document.body.removeChild(oInput) + message.success('澶嶅埗鎴愬姛銆�') + }}>{card.name}</div> + <div className="content"> + {card.errors && card.errors.map((err, index) => { + if (err.level === 0) { + return <span key={index} className="error">{err.detail}</span> + } else { + return <span key={index} className="waring">{err.detail}锛�</span> + } + })} + </div> + </div> + </div> + </div> + ) + } +} + +export default antvG6Chart \ No newline at end of file diff --git a/src/menu/components/chart/antv-X6/index.scss b/src/menu/components/chart/antv-X6/index.scss new file mode 100644 index 0000000..5d8ba6f --- /dev/null +++ b/src/menu/components/chart/antv-X6/index.scss @@ -0,0 +1,68 @@ +.menu-scatter-chart-edit-box { + position: relative; + box-sizing: border-box; + background: #ffffff; + background-position: center center; + background-repeat: no-repeat; + background-size: cover; + + .canvas { + margin: 0px; + padding: 15px; + letter-spacing: 0px; + } + + .chart-header { + position: relative; + height: 45px; + border-bottom: 1px solid #e8e8e8; + overflow: hidden; + padding-right: 35px; + + .chart-title { + text-decoration: inherit; + font-weight: inherit; + font-style: inherit; + float: left; + line-height: 45px; + margin-left: 10px; + position: relative; + z-index: 1; + } + } + + >.anticon-tool { + position: absolute; + right: 1px; + top: 1px; + z-index: 3; + font-size: 16px; + padding: 5px; + cursor: pointer; + color: rgba(0, 0, 0, 0.85); + background: rgba(255, 255, 255, 0.55); + } + + .model-menu-action-list { + position: absolute; + right: 0px; + top: 30px; + z-index: 4; + font-size: 16px; + + .ant-row .anticon-plus { + float: right; + } + + .page-card { + float: right; + } + } + .normal-header + .canvas + .model-menu-action-list { + top: 45px; + } +} +.menu-scatter-chart-edit-box:hover { + z-index: 1; + box-shadow: 0px 0px 4px #1890ff; +} -- Gitblit v1.8.0