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