From e41a64966b7832baffe96c21d1ea77ef6adb2905 Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期四, 14 十月 2021 18:31:55 +0800
Subject: [PATCH] 2021-10-14

---
 package-lock.json                                                    |   34 
 src/menu/components/chart/antv-pie/chartcompile/formconfig.jsx       |   19 
 src/menu/components/group/groupcomponents/index.jsx                  |    1 
 src/menu/components/chart/chart-custom/index.jsx                     | 1123 -----------------------
 src/menu/components/chart/antv-scatter/chartcompile/formconfig.jsx   |    4 
 src/menu/components/tabs/tabcomponents/index.jsx                     |    1 
 src/menu/components/chart/chart-custom/chartcompile/index.scss       |   35 
 src/menu/components/chart/chart-custom/chartcompile/index.jsx        |  623 ------------
 src/menu/components/chart/antv-dashboard/chartcompile/formconfig.jsx |    4 
 src/menu/menushell/card.jsx                                          |    3 
 src/menu/components/chart/chart-custom/index.scss                    |    6 
 src/tabviews/custom/components/chart/custom-chart/index.jsx          |  382 ++++++++
 src/views/menudesign/index.jsx                                       |    2 
 src/menu/modulesource/option.jsx                                     |    4 
 src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx       |    4 
 src/tabviews/custom/components/share/tabtransfer/index.jsx           |    7 
 src/tabviews/custom/components/chart/custom-chart/index.scss         |   57 +
 src/tabviews/custom/components/group/normal-group/index.jsx          |    7 
 src/menu/components/chart/chart-custom/chartcompile/formconfig.jsx   |  434 --------
 src/menu/components/group/groupcomponents/card.jsx                   |    3 
 src/tabviews/custom/index.jsx                                        |    9 
 package.json                                                         |    2 
 src/menu/components/share/normalform/index.jsx                       |    2 
 src/menu/components/tabs/tabcomponents/card.jsx                      |    3 
 src/menu/menushell/index.jsx                                         |    1 
 25 files changed, 600 insertions(+), 2,170 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 227cd3e..117451b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4459,7 +4459,7 @@
       "dependencies": {
         "immutable": {
           "version": "3.7.6",
-          "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz",
+          "resolved": "http://registry.npm.taobao.org/immutable/download/immutable-3.7.6.tgz",
           "integrity": "sha1-E7TTyxK++hVIKib+Gy665kAHHks="
         }
       }
@@ -7541,11 +7541,19 @@
       }
     },
     "echarts": {
-      "version": "4.5.0",
-      "resolved": "https://registry.npmjs.org/echarts/-/echarts-4.5.0.tgz",
-      "integrity": "sha512-q9M0errodeX/786uPifro76x0elbrUQkbSHh235QzbkaASuvP9AQoMErhGBno4iC/yq6kFDLqgmm3XCPWQGLzA==",
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/echarts/-/echarts-5.2.1.tgz",
+      "integrity": "sha512-OJ79b22eqRfbSV8vYmDKmA+XWfNbr0Uk/OafWcFNIGDWti2Uw9A6eVCiJLmqPa9Sk+EWL+t5v26aak0z3gxiZw==",
       "requires": {
-        "zrender": "4.1.2"
+        "tslib": "2.3.0",
+        "zrender": "5.2.1"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
+          "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
+        }
       }
     },
     "echarts-for-react": {
@@ -21347,9 +21355,19 @@
       }
     },
     "zrender": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/zrender/-/zrender-4.1.2.tgz",
-      "integrity": "sha512-MJYEo1ZOVesjxYsfcGtPXnUREmh4ACMV08QZLGZ3S7D1xOd96iz3O6nf6pv5PHb5NSHkbizr7ChSIgtAGwncvA=="
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.2.1.tgz",
+      "integrity": "sha512-M3bPGZuyLTNBC6LiNKXJwSCtglMp8XUEqEBG+2MdICDI3d1s500Y4P0CzldQGsqpRVB7fkvf3BKQQRxsEaTlsw==",
+      "requires": {
+        "tslib": "2.3.0"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
+          "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
+        }
+      }
     },
     "zscroller": {
       "version": "0.4.8",
diff --git a/package.json b/package.json
index b31ef50..5ed39dd 100644
--- a/package.json
+++ b/package.json
@@ -31,7 +31,7 @@
     "dotenv": "6.2.0",
     "dotenv-expand": "4.2.0",
     "dragact": "^0.2.12",
-    "echarts": "^4.5.0",
+    "echarts": "^5.2.1",
     "echarts-for-react": "^2.0.15-beta.1",
     "eslint": "^6.1.0",
     "eslint-config-react-app": "^5.0.1",
diff --git a/src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx b/src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx
index ac311aa..f3b35e2 100644
--- a/src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx
+++ b/src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx
@@ -8,6 +8,7 @@
  * @param {object} card       // 鍥捐〃瀵硅薄
  */
 export function getBaseForm (card) {
+  let appType = sessionStorage.getItem('appType')
   let roleList = sessionStorage.getItem('sysRoles')
   if (roleList) {
     try {
@@ -63,7 +64,8 @@
       initVal: card.blacklist || [],
       multi: true,
       required: false,
-      options: roleList
+      options: roleList,
+      forbid: !!appType
     },
     // {
     //   type: 'cascader',
diff --git a/src/menu/components/chart/antv-dashboard/chartcompile/formconfig.jsx b/src/menu/components/chart/antv-dashboard/chartcompile/formconfig.jsx
index 121440f..222db5a 100644
--- a/src/menu/components/chart/antv-dashboard/chartcompile/formconfig.jsx
+++ b/src/menu/components/chart/antv-dashboard/chartcompile/formconfig.jsx
@@ -8,6 +8,7 @@
  * @param {object} card       // 鍥捐〃瀵硅薄
  */
 export function getBaseForm (card) {
+  let appType = sessionStorage.getItem('appType')
   let roleList = sessionStorage.getItem('sysRoles')
   if (roleList) {
     try {
@@ -63,7 +64,8 @@
       initVal: card.blacklist || [],
       multi: true,
       required: false,
-      options: roleList
+      options: roleList,
+      forbid: !!appType
     }
   ]
 }
diff --git a/src/menu/components/chart/antv-pie/chartcompile/formconfig.jsx b/src/menu/components/chart/antv-pie/chartcompile/formconfig.jsx
index 1d23172..a4d79f5 100644
--- a/src/menu/components/chart/antv-pie/chartcompile/formconfig.jsx
+++ b/src/menu/components/chart/antv-pie/chartcompile/formconfig.jsx
@@ -84,15 +84,6 @@
       required: true
     },
     {
-      type: 'select',
-      key: 'blacklist',
-      label: '榛戝悕鍗�',
-      initVal: card.blacklist || [],
-      multi: true,
-      required: false,
-      options: roleList
-    },
-    {
       type: 'cascader',
       key: 'linkmenu',
       label: '鍏宠仈鑿滃崟',
@@ -123,6 +114,16 @@
         { value: 'blank', text: '鏂扮獥鍙�' },
         { value: 'self', text: '褰撳墠绐楀彛' }
       ]
+    },
+    {
+      type: 'select',
+      key: 'blacklist',
+      label: '榛戝悕鍗�',
+      initVal: card.blacklist || [],
+      multi: true,
+      required: false,
+      options: roleList,
+      forbid: !!appType
     }
   ]
 }
diff --git a/src/menu/components/chart/antv-scatter/chartcompile/formconfig.jsx b/src/menu/components/chart/antv-scatter/chartcompile/formconfig.jsx
index f63fa94..bd73720 100644
--- a/src/menu/components/chart/antv-scatter/chartcompile/formconfig.jsx
+++ b/src/menu/components/chart/antv-scatter/chartcompile/formconfig.jsx
@@ -3,6 +3,7 @@
  * @param {object} card       // 鍥捐〃瀵硅薄
  */
 export function getBaseForm (card) {
+  let appType = sessionStorage.getItem('appType')
   let roleList = sessionStorage.getItem('sysRoles')
   if (roleList) {
     try {
@@ -58,7 +59,8 @@
       initVal: card.blacklist || [],
       multi: true,
       required: false,
-      options: roleList
+      options: roleList,
+      forbid: !!appType
     }
   ]
 }
diff --git a/src/menu/components/chart/chart-custom/chartcompile/formconfig.jsx b/src/menu/components/chart/chart-custom/chartcompile/formconfig.jsx
index ac311aa..58786ea 100644
--- a/src/menu/components/chart/chart-custom/chartcompile/formconfig.jsx
+++ b/src/menu/components/chart/chart-custom/chartcompile/formconfig.jsx
@@ -1,13 +1,9 @@
-import zhCN from '@/locales/zh-CN/model.js'
-import enUS from '@/locales/en-US/model.js'
-
-const Formdict = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
-
 /**
  * @description 鑾峰彇鍥捐〃瑙嗗浘閰嶇疆琛ㄥ崟
  * @param {object} card       // 鍥捐〃瀵硅薄
  */
 export function getBaseForm (card) {
+  let appType = sessionStorage.getItem('appType')
   let roleList = sessionStorage.getItem('sysRoles')
   if (roleList) {
     try {
@@ -34,6 +30,17 @@
       initVal: card.name,
       tooltip: '鐢ㄤ簬缁勪欢闂寸殑鍖哄垎銆�',
       required: true
+    },
+    {
+      type: 'radio',
+      key: 'chartType',
+      label: '鍥捐〃绫诲瀷',
+      initVal: card.chartType || 'antv',
+      required: true,
+      options: [
+        { value: 'antv', text: 'antv' },
+        { value: 'echarts', text: 'echarts' }
+      ]
     },
     {
       type: 'number',
@@ -63,7 +70,8 @@
       initVal: card.blacklist || [],
       multi: true,
       required: false,
-      options: roleList
+      options: roleList,
+      forbid: !!appType
     },
     // {
     //   type: 'cascader',
@@ -85,416 +93,6 @@
     //   forbid: appType !== 'pc',
     //   options: menulist
     // },
-    // {
-    //   type: 'radio',
-    //   key: 'open',
-    //   label: '鎵撳紑鏂瑰紡',
-    //   initVal: card.open || 'blank',
-    //   required: false,
-    //   forbid: appType !== 'pc',
-    //   options: [
-    //     { value: 'blank', text: '鏂扮獥鍙�' },
-    //     { value: 'self', text: '褰撳墠绐楀彛' }
-    //   ]
-    // }
+    
   ]
-}
-
-/**
- * @description 鑾峰彇鍥捐〃瑙嗗浘閰嶇疆琛ㄥ崟
- * @param {object} card       // 鍥捐〃瀵硅薄
- * @param {Array}  columns    // 鏄剧ず鍒�
- */
-export function getOptionForm (card, columns) {
-  let appType = sessionStorage.getItem('appType')
-  let shapes = []
-
-  if (card.chartType === 'line') {
-    shapes = [
-      { field: 'smooth', label: 'smooth' },
-      { field: 'line', label: 'line' },
-      { field: 'dot', label: 'dot' },
-      { field: 'dash', label: 'dash' },
-      { field: 'hv', label: 'hv' },
-      { field: 'vh', label: 'vh' },
-      { field: 'hvh', label: 'hvh' },
-      { field: 'vhv', label: 'vhv' }
-    ]
-  } else if (card.chartType === 'bar') {
-    shapes = [
-      { field: 'rect', label: 'rect' },
-      { field: 'hollow-rect', label: 'hollow-rect' },
-      { field: 'line', label: 'line' },
-      { field: 'tick', label: 'tick' },
-      { field: 'funnel', label: 'funnel' },
-      { field: 'pyramid', label: 'pyramid' }
-    ]
-  }
-
-  let xfields = columns.filter(item => /^Nvarchar/ig.test(item.datatype))
-  let yfields = columns.filter(item => /^(Int|Decimal)/ig.test(item.datatype))
-
-  let labelOptions = [{
-    value: 'false',
-    text: '闅愯棌'
-  }, {
-    value: 'true',
-    text: '鏄剧ず'
-  }]
-
-  if (card.chartType === 'bar') {
-    labelOptions[1].text = '澶栭儴'
-    labelOptions.push(...[{
-      value: 'top',
-      text: '椤堕儴'
-    }, {
-      value: 'middle',
-      text: '涓棿'
-    }, {
-      value: 'bottom',
-      text: '搴曢儴'
-    }])
-  }
-
-  return [
-    {
-      type: 'radio',
-      key: 'datatype',
-      label: '鏁版嵁绫诲瀷',
-      initVal: card.datatype || 'query',
-      tooltip: '缁熻鍥捐〃閫傜敤浜庡睍绀烘暟鎹被鍨嬩负鍔ㄦ�佸�笺��',
-      required: false,
-      options: [
-        { value: 'query', text: Formdict['header.form.query'] },
-        { value: 'statistics', text: Formdict['header.form.statistics'] }
-      ]
-    }, {
-      type: 'select',
-      key: 'Xaxis',
-      label: 'X-杞�',
-      initVal: card.Xaxis || '',
-      required: true,
-      options: xfields
-    }, {
-      type: 'select',
-      key: 'InfoType',
-      label: '绫诲瀷',
-      initVal: card.InfoType || '',
-      hidden: card.datatype !== 'statistics',
-      required: true,
-      options: xfields
-    }, {
-      type: 'select',
-      key: 'InfoValue',
-      label: '鍊�',
-      initVal: card.InfoValue || '',
-      hidden: card.datatype !== 'statistics',
-      required: true,
-      options: yfields
-    }, {
-      type: 'select',
-      key: 'legend',
-      label: '鍥句緥浣嶇疆',
-      initVal: card.legend || 'bottom',
-      required: false,
-      options: [
-        { field: 'bottom', label: '涓�' },
-        { field: 'bottom-left', label: '涓嬪乏' },
-        { field: 'bottom-right', label: '涓嬪彸' },
-        { field: 'top', label: '涓�' },
-        { field: 'top-left', label: '涓婂乏' },
-        { field: 'top-right', label: '涓婂彸' },
-        { field: 'right', label: '鍙�' },
-        { field: 'right-top', label: '鍙充笂' },
-        { field: 'right-bottom', label: '鍙充笅' },
-        { field: 'left', label: '宸�' },
-        { field: 'left-top', label: '宸︿笂' },
-        { field: 'left-bottom', label: '宸︿笅' },
-        { field: 'hidden', label: '闅愯棌' }
-      ]
-    }, {
-      type: 'select',
-      key: 'Yaxis',
-      label: 'Y-杞�',
-      initVal: card.Yaxis || [],
-      multi: true, // 澶氶��
-      hidden: card.datatype === 'statistics',
-      required: true,
-      options: yfields
-    }, {
-      type: 'select',
-      key: 'shape',
-      label: '褰㈢姸',
-      initVal: card.shape || (shapes[0] && shapes[0].field),
-      required: false,
-      options: shapes
-    }, {
-      type: 'radio',
-      key: 'tooltip',
-      label: '鎮诞鎻愮ず',
-      initVal: card.tooltip || 'true',
-      required: false,
-      options: [{
-        value: 'true',
-        text: '鏄剧ず'
-      }, {
-        value: 'false',
-        text: '闅愯棌'
-      }]
-    }, {
-      type: 'radio',
-      key: 'point',
-      label: '鐐瑰浘',
-      initVal: card.point || 'false',
-      required: false,
-      forbid: !['line'].includes(card.chartType),
-      options: [{
-        value: 'true',
-        text: '鏄剧ず'
-      }, {
-        value: 'false',
-        text: '闅愯棌'
-      }]
-    }, {
-      type: 'radio',
-      key: 'transpose',
-      label: '鍙樻崲',
-      initVal: card.transpose || 'false',
-      tooltip: '妯旱鍧愭爣杞翠氦鎹�',
-      required: false,
-      options: [{
-        value: 'true',
-        text: Formdict['model.true']
-      }, {
-        value: 'false',
-        text: Formdict['model.false']
-      }]
-    }, {
-      type: 'radio',
-      key: 'show',
-      label: '鏍煎紡鍖�',
-      initVal: card.show || 'value',
-      required: false,
-      options: [{
-        value: 'value',
-        text: '鏃�'
-      }, {
-        value: 'percent',
-        text: '鐧惧垎姣�'
-      }]
-    }, {
-      type: labelOptions.length > 20 ? 'select' : 'radio',
-      key: 'label',
-      label: '鏍囩',
-      initVal: card.label || 'false',
-      required: false,
-      options: labelOptions
-    }, {
-      type: 'radio',
-      key: 'labelColor',
-      label: '鏍囩棰滆壊',
-      initVal: card.labelColor || 'system',
-      tooltip: '浣跨敤绯荤粺鑹叉椂锛屼娇鐢ㄨ壊绯婚�夐」璁剧疆鐨勭郴缁熼鑹诧紝浣跨敤鑷畾涔変负棰滆壊璁剧疆涓畾涔夌殑鍥惧舰棰滆壊銆�',
-      required: false,
-      options: [{
-        value: 'system',
-        text: '绯荤粺'
-      }, {
-        value: 'custom',
-        text: '鑷畾涔�'
-      }]
-    // }, {
-    //   type: 'radio',
-    //   key: 'offset',
-    //   label: '鏍囨敞浣嶇疆',
-    //   initVal: card.offset || 'outer',
-    //   required: false,
-    //   options: [{
-    //     value: 'outer',
-    //     text: '澶栭儴'
-    //   }, {
-    //     value: 'inner',
-    //     text: '鍐呴儴'
-    //   }],
-    //   forbid: card.chartType !== 'bar'
-    }, {
-      type: 'radio',
-      key: 'adjust',
-      label: '澶氭煴鎺掑垪',
-      initVal: card.adjust || 'dodge',
-      required: false,
-      forbid: !['bar'].includes(card.chartType),
-      options: [{
-        value: 'dodge',
-        text: '鍒嗙粍'
-      }, {
-        value: 'stack',
-        text: '鍫嗗彔'
-      }]
-    }, {
-      type: 'radio',
-      key: 'area',
-      label: '闈㈢Н鍥�',
-      initVal: card.area || 'false',
-      // tooltip: '浠呭湪褰㈢姸涓簊mooth鏃舵湁鏁堛��',
-      required: false,
-      forbid: ['bar'].includes(card.chartType),
-      options: [{
-        value: 'true',
-        text: '鏄剧ず'
-      }, {
-        value: 'false',
-        text: '涓嶆樉绀�'
-      }]
-    }, {
-      type: 'radio',
-      key: 'repeat',
-      label: '閲嶅鏁版嵁',
-      initVal: card.repeat || 'unrepeat',
-      required: false,
-      options: [{
-        value: 'unrepeat',
-        text: '鍘婚噸'
-      }, {
-        value: 'average',
-        text: '骞冲潎'
-      }, {
-        value: 'cumsum',
-        text: '绱姞'
-      }]
-    }, {
-      type: 'radio',
-      key: 'coordinate',
-      label: '鍧愭爣',
-      initVal: card.coordinate || 'angle',
-      required: false,
-      options: [{
-        value: 'angle',
-        text: '浜岀淮鍧愭爣'
-      }, {
-        value: 'polar',
-        text: '鏋佸潗鏍�'
-      }]
-    }, {
-      type: 'radio',
-      key: 'grid',
-      label: '缃戞牸绾�',
-      initVal: card.grid || 'show',
-      required: false,
-      options: [{
-        value: 'show',
-        text: '鏄剧ず'
-      }, {
-        value: 'hidden',
-        text: '闅愯棌'
-      }]
-    }, {
-      type: 'radio',
-      key: 'y_line',
-      label: 'y杞磋竟绾�',
-      initVal: card.y_line || 'hidden',
-      tooltip: '鍥惧舰宸︿晶鎴栧彸渚х殑杈圭嚎銆�',
-      required: false,
-      options: [{
-        value: 'show',
-        text: '鏄剧ず'
-      }, {
-        value: 'hidden',
-        text: '闅愯棌'
-      }]
-    }, {
-      type: 'number',
-      key: 'barSize',
-      label: '鏌卞舰瀹藉害',
-      tooltip: '绌哄�兼椂锛屽搴﹁嚜閫傚簲銆�',
-      min: 5,
-      max: 100,
-      decimal: 0,
-      initVal: card.barSize,
-      forbid: !['bar'].includes(card.chartType),
-      required: false
-    }, {
-      type: 'number',
-      key: 'barRadius',
-      label: '鏌卞舰鍦嗚',
-      tooltip: '鏌卞舰鍥句笂绔渾瑙掋��',
-      min: 0,
-      max: 200,
-      decimal: 0,
-      initVal: card.barRadius || 0,
-      forbid: !['bar'].includes(card.chartType),
-      required: false
-    }, {
-      type: 'number',
-      key: 'min',
-      label: '鏈�灏忓��',
-      tooltip: 'y杞存渶灏忓�硷紝涓虹┖鏃惰嚜閫傚簲銆�',
-      initVal: card.min,
-      required: false
-    }, {
-      type: 'number',
-      key: 'max',
-      label: '鏈�澶у��',
-      tooltip: 'y杞存渶澶у�硷紝涓虹┖鏃惰嚜閫傚簲銆�',
-      initVal: card.max,
-      required: false
-    }, {
-      type: 'color',
-      key: 'color',
-      label: '鑹茬郴',
-      initVal: card.color || 'rgba(0, 0, 0, 0.65)',
-      tooltip: '鍧愭爣杞存彁绀烘枃瀛楀強绀轰緥鐨勯鑹层��',
-      required: false
-    }, {
-      type: 'color',
-      key: 'lineColor',
-      label: '杞寸嚎棰滆壊',
-      initVal: card.lineColor,
-      tooltip: '鍧愭爣杞寸嚎鐨勯鑹诧紝鍖呮嫭x杞淬�亂杞村強缃戞牸绾裤��',
-      allowClear: true,
-      required: false
-    }, {
-      type: 'color',
-      key: 'selectColor',
-      label: '閫変腑棰滆壊',
-      initVal: card.selectColor || '',
-      tooltip: '閫変腑鏌卞舰鍥剧殑棰滆壊锛屽湪浜や簰鏁堟灉銆婂厓绱犻�変腑锛堝閫夛級銆嬪拰銆婂厓绱犻�変腑锛堝崟閫夛級銆嬩腑鏈夋晥锛岃嚜瀹氫箟璁剧疆涓棤鏁堛��',
-      forbid: !['bar'].includes(card.chartType),
-      allowClear: true,
-      required: false
-    }, {
-      type: 'number',
-      key: 'rotate',
-      label: '鏃嬭浆',
-      tooltip: '鍧愭爣杞存爣娉ㄦ枃鏈殑鏃嬭浆瑙掑害銆�',
-      min: 0,
-      max: 360,
-      decimal: 0,
-      initVal: card.rotate,
-      forbid: appType !== 'mob',
-      required: false
-    }, {
-      type: 'select',
-      key: 'interaction',
-      label: '浜や簰鏁堟灉',
-      initVal: card.interaction || [],
-      multi: true,
-      required: false,
-      forbid: appType === 'mob',
-      options: [
-        { value: 'element-active', label: '鍏冪礌鑱氱劍' },
-        { value: 'element-selected', label: '鍏冪礌閫変腑锛堝閫夛級' },
-        { value: 'element-single-selected', label: '鍏冪礌閫変腑锛堝崟閫夛級' },
-        { value: 'active-region', label: '鑳屾櫙妗�' },
-        { value: 'view-zoom', label: '瑙嗗浘缂╂斁' },
-        { value: 'element-highlight', label: '鍏冪礌楂樹寒' },
-        { value: 'element-highlight-by-color', label: '鍚岃壊鍏冪礌楂樹寒' },
-        { value: 'element-highlight-by-x', label: '鍚孹杞村厓绱犻珮浜�' },
-        { value: 'legend-filter', label: '鍥句緥杩囨护' },
-        { value: 'legend-active', label: '鍥句緥鑱氱劍' },
-        { value: 'legend-highlight', label: '鍥句緥楂樹寒' },
-        { value: 'brush', label: '閫夋杩囨护' },
-      ]
-    }
-  ]
-}
+}
\ No newline at end of file
diff --git a/src/menu/components/chart/chart-custom/chartcompile/index.jsx b/src/menu/components/chart/chart-custom/chartcompile/index.jsx
index 3f31823..e59b022 100644
--- a/src/menu/components/chart/chart-custom/chartcompile/index.jsx
+++ b/src/menu/components/chart/chart-custom/chartcompile/index.jsx
@@ -1,20 +1,17 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-import { is, fromJS } from 'immutable'
-import { Modal, Form, Row, Col, Select, Icon, Radio, Tooltip, Input, InputNumber, Tabs, Button } from 'antd'
+import { fromJS } from 'immutable'
+import { Modal, Form, Icon, Tabs } from 'antd'
 
-import Utils from '@/utils/utils.js'
-import { chartColors } from '@/utils/option.js'
-import { getBaseForm, getOptionForm } from './formconfig'
+import { getBaseForm } from './formconfig'
 import asyncComponent from '@/utils/asyncComponent'
-import ColorSketch from '@/mob/colorsketch'
 import './index.scss'
 
 const { TabPane } = Tabs
-const EditTable = asyncComponent(() => import('@/templates/zshare/editTable'))
 const NormalForm = asyncComponent(() => import('@/menu/components/share/normalform'))
+const CodeMirror = asyncComponent(() => import('@/templates/zshare/codemirror'))
 
-class LineChartDrawerForm extends Component {
+class CustomChartDrawerForm extends Component {
   static propTpyes = {
     dict: PropTypes.object,
     plot: PropTypes.object,
@@ -23,464 +20,28 @@
   }
 
   state = {
-    view: 'normal',
-    ramp: 'false',
+    view: 'base',
     visible: false,
-    datatype: '',
     plot: null,
-    formlist: null,
     baseFormlist: null,
-    fieldName: null,
-    colorColumns: [
-      {
-        title: '鎸囨爣',
-        dataIndex: 'label',
-        editable: false,
-        width: '40%'
-      },
-      {
-        title: '棰滆壊',
-        dataIndex: 'color',
-        inputType: 'color',
-        editable: true,
-        width: '40%',
-        render: (text, record) => {
-          return (<div style={{width: '80px', height: '23px', background: text}}></div>)
-        }
-      },
-    ],
-    rampColorColumns: [
-      {
-        title: '鎸囨爣',
-        dataIndex: 'label',
-        editable: false,
-        width: '20%'
-      },
-      {
-        title: '棰滆壊1',
-        dataIndex: 'color',
-        inputType: 'color',
-        editable: true,
-        width: '30%',
-        render: (text, record) => {
-          return (<div style={{width: '80px', height: '23px', background: text}}></div>)
-        }
-      },
-      {
-        title: '棰滆壊2',
-        dataIndex: 'color1',
-        inputType: 'color',
-        editable: true,
-        width: '30%',
-        render: (text, record) => {
-          return (<div style={{width: '80px', height: '23px', background: text}}></div>)
-        }
-      },
-    ],
-    statColorColumns: [
-      {
-        title: '鎸囨爣',
-        dataIndex: 'type',
-        inputType: 'input',
-        editable: true,
-        width: '40%'
-      },
-      {
-        title: '棰滆壊',
-        dataIndex: 'color',
-        inputType: 'color',
-        editable: true,
-        width: '40%',
-        render: (text, record) => {
-          return (<div style={{width: '80px', height: '23px', background: text}}></div>)
-        }
-      },
-    ],
-    rampStatColorColumns: [
-      {
-        title: '鎸囨爣',
-        dataIndex: 'type',
-        inputType: 'input',
-        editable: true,
-        width: '20%'
-      },
-      {
-        title: '棰滆壊1',
-        dataIndex: 'color',
-        inputType: 'color',
-        editable: true,
-        width: '30%',
-        render: (text, record) => {
-          return (<div style={{width: '80px', height: '23px', background: text}}></div>)
-        }
-      },
-      {
-        title: '棰滆壊2',
-        dataIndex: 'color1',
-        inputType: 'color',
-        editable: true,
-        width: '30%',
-        render: (text, record) => {
-          return (<div style={{width: '80px', height: '23px', background: text}}></div>)
-        }
-      },
-    ],
-    cusColumns: [
-      {
-        title: '鎸囨爣',
-        dataIndex: 'name',
-        editable: false,
-        width: '14%'
-      },
-      {
-        title: '褰㈢姸',
-        dataIndex: 'shape',
-        inputType: 'cascader',
-        editable: true,
-        width: '12%',
-        render: (text, record) => {
-          return text.join(' / ').replace('line', '鎶樼嚎').replace('bar', '鏌卞舰')
-        },
-        options: [
-          {
-            value: 'line',
-            label: '鎶樼嚎',
-            children: [
-              { value: 'smooth', label: 'smooth' },
-              { value: 'line', label: 'line' },
-              { value: 'dot', label: 'dot' },
-              { value: 'dash', label: 'dash' },
-              { value: 'hv', label: 'hv' },
-              { value: 'vh', label: 'vh' },
-              { value: 'hvh', label: 'hvh' },
-              { value: 'vhv', label: 'vhv' }
-            ]
-          },
-          {
-            value: 'bar',
-            label: '鏌卞舰',
-            children: [
-              { value: 'rect', label: 'rect' },
-              { value: 'hollow-rect', label: 'hollow-rect' },
-              { value: 'line', label: 'line' },
-              { value: 'tick', label: 'tick' },
-              { value: 'funnel', label: 'funnel' },
-              { value: 'pyramid', label: 'pyramid' }
-            ],
-          }
-        ]
-      },
-      {
-        title: '鍧愭爣杞�',
-        dataIndex: 'axis',
-        inputType: 'select',
-        editable: true,
-        width: '12%',
-        options: [
-          { value: 'true', text: '鏄剧ず'},
-          { value: 'false', text: '闅愯棌'}
-        ],
-        render: (text, record) => {
-          let trans = {'true': '鏄剧ず', 'false': '闅愯棌'}
-          return trans[text] || '闅愯棌'
-        }
-      },
-      {
-        title: '鏍囨敞',
-        dataIndex: 'label',
-        inputType: 'select',
-        editable: true,
-        width: '12%',
-        options: [
-          { value: 'true', text: '鏄剧ず'},
-          { value: 'false', text: '闅愯棌'}
-        ],
-        render: (text, record) => {
-          let trans = {'true': '鏄剧ず', 'false': '闅愯棌'}
-          return trans[text] || '闅愯棌'
-        }
-      },
-      {
-        title: '鏍囬',
-        dataIndex: 'title',
-        inputType: 'select',
-        editable: true,
-        width: '12%',
-        options: [
-          { value: 'true', text: '鏄剧ず'},
-          { value: 'false', text: '闅愯棌'}
-        ],
-        render: (text, record) => {
-          let trans = {'true': '鏄剧ず', 'false': '闅愯棌'}
-          return trans[text] || '鏄剧ず'
-        }
-      },
-      {
-        title: '鏈�灏忓��',
-        dataIndex: 'min',
-        inputType: 'number',
-        editable: true,
-        required: false,
-        width: '12%'
-      },
-      {
-        title: '鏈�澶у��',
-        dataIndex: 'max',
-        inputType: 'number',
-        editable: true,
-        required: false,
-        width: '12%'
-      },
-    ]
   }
 
   showDrawer = () => {
     const { config } = this.props
 
-    let fieldName = {}
-    config.columns.forEach(col => {
-      if (col.field) {
-        fieldName[col.field] = col.label
-      }
-    })
-
-    if (config.plot.correction) {
-      delete config.plot.correction // 鏁版嵁淇锛堝凡寮冪敤锛�
-      config.plot.barSize = 35
-    }
-
     this.setState({
       visible: true,
-      view: 'normal',
-      ramp: config.plot.ramp || 'false',
-      datatype: config.plot.datatype || 'query',
-      fieldName: fieldName,
+      view: 'base',
       plot: fromJS(config.plot).toJS(),
       baseFormlist: getBaseForm(config.plot),
-      formlist: getOptionForm(config.plot, config.columns)
     })
-  }
-
-  radioChange = (e, key) => {
-    const { formlist } = this.state
-    let val = e.target.value
-
-    if (key === 'datatype') {
-      this.setState({
-        datatype: val,
-        formlist: formlist.map(item => {
-          if (['Yaxis'].includes(item.key)) {
-            item.hidden = val === 'statistics'
-          } else if (['InfoType', 'InfoValue'].includes(item.key)) {
-            item.hidden = val !== 'statistics'
-          }
-          return item
-        })
-      })
-    }
-  }
-
-  getFields() {
-    const { formlist } = this.state
-    const { getFieldDecorator } = this.props.form
-    const fields = []
-
-    if (!formlist) {
-      return fields
-    }
-
-    formlist.forEach((item, index) => {
-      if (item.hidden || item.forbid) return
-      
-      if (item.type === 'text') {
-        fields.push(
-          <Col span={12} key={index}>
-            <Form.Item label={item.tooltip ?
-              <Tooltip placement="topLeft" title={item.tooltip}>
-                <Icon type="question-circle" />
-                {item.label}
-              </Tooltip> : item.label
-            }>
-              {getFieldDecorator(item.key, {
-                initialValue: item.initVal,
-                rules: [
-                  {
-                    required: !!item.required,
-                    message: this.props.dict['form.required.input'] + item.label + '!'
-                  }
-                ]
-              })(<Input placeholder="" autoComplete="off" disabled={item.readonly} onPressEnter={this.onSubmit}/>)}
-            </Form.Item>
-          </Col>
-        )
-      } else if (item.type === 'number') {
-        fields.push(
-          <Col span={12} key={index}>
-            <Form.Item label={item.tooltip ?
-              <Tooltip placement="topLeft" title={item.tooltip}>
-                <Icon type="question-circle" />
-                {item.label}
-              </Tooltip> : item.label
-            }>
-              {getFieldDecorator(item.key, {
-                initialValue: item.initVal,
-                rules: [
-                  {
-                    required: !!item.required,
-                    message: this.props.dict['form.required.input'] + item.label + '!'
-                  }
-                ]
-              })(<InputNumber min={item.min} max={item.max} precision={item.decimal} onPressEnter={this.onSubmit}/>)}
-            </Form.Item>
-          </Col>
-        )
-      } else if (item.type === 'select') { // 涓嬫媺
-        fields.push(
-          <Col span={12} key={index}>
-            <Form.Item label={item.tooltip ?
-              <Tooltip placement="topLeft" title={item.tooltip}>
-                <Icon type="question-circle" />
-                {item.label}
-              </Tooltip> : item.label
-            }>
-              {getFieldDecorator(item.key, {
-                initialValue: item.initVal,
-                rules: [
-                  {
-                    required: !!item.required,
-                    message: this.props.dict['form.required.select'] + item.label + '!'
-                  }
-                ]
-              })(
-                <Select mode={item.multi ? 'multiple' : ''}>
-                  {item.options.map((option, index) =>
-                    <Select.Option key={index} value={option.field || option.value}>
-                      {option.label || option.text}
-                    </Select.Option>
-                  )}
-                </Select>
-              )}
-            </Form.Item>
-          </Col>
-        )
-      } else if (item.type === 'radio') {
-        fields.push(
-          <Col span={12} key={index}>
-            <Form.Item label={item.tooltip ?
-              <Tooltip placement="topLeft" title={item.tooltip}>
-                <Icon type="question-circle" />
-                {item.label}
-              </Tooltip> : item.label
-            }>
-              {getFieldDecorator(item.key, {
-                initialValue: item.initVal,
-                rules: [
-                  {
-                    required: !!item.required,
-                    message: this.props.dict['form.required.select'] + item.label + '!'
-                  }
-                ]
-              })(
-                <Radio.Group style={{whiteSpace: 'nowrap'}} disabled={item.readonly} onChange={(e) => this.radioChange(e, item.key)}>
-                  {item.options.map(option => {
-                    return (
-                      <Radio key={option.value} value={option.value}>{option.text}</Radio>
-                    )
-                  })}
-                </Radio.Group>
-              )}
-            </Form.Item>
-          </Col>
-        )
-      } else if (item.type === 'color') {
-        fields.push(
-          <Col span={12} key={index}>
-            <Form.Item label={item.tooltip ?
-              <Tooltip placement="topLeft" title={item.tooltip}>
-                <Icon type="question-circle" />
-                {item.label}
-              </Tooltip> : item.label
-            }>
-              {getFieldDecorator(item.key, {
-                initialValue: item.initVal
-              })(
-                <ColorSketch allowClear={item.allowClear} />
-              )}
-            </Form.Item>
-          </Col>
-        )
-      }
-    })
-    return fields
-  }
-
-  enabledChange = (e) => {
-    const { plot } = this.state
-    let val = e.target.value
-
-    this.setState({plot: {...plot, enabled: val}})
-  }
-
-  mutilBarChange = (e) => {
-    const { plot } = this.state
-    let val = e.target.value
-
-    this.setState({plot: {...plot, mutilBar: val}})
-  }
-
-  rampChange = (e) => {
-    const { plot } = this.state
-    let val = e.target.value
-    let colors = plot.colors || []
-
-    if (val === 'true') {
-      colors = colors.map(item => {
-        item.color1 = item.color1 || item.color
-        return item
-      })
-    }
-
-    this.setState({plot: {...plot, colors, ramp: val}, ramp: val})
-  }
-
-  rampDirectionChange = (e) => {
-    const { plot } = this.state
-    let val = e.target.value
-
-    this.setState({plot: {...plot, rampDirection: val}})
   }
 
   onSubmit = () => {
     const { config } = this.props
     const { plot, view } = this.state
 
-    if (view === 'normal') {
-      this.props.form.validateFieldsAndScroll((err, values) => {
-        if (!err) {
-          let _plot = {...plot, ...values}
-
-          if (values.datatype === 'statistics' || values.datatype !== plot.datatype) {
-            _plot.enabled = 'false'
-            _plot.customs = []
-          } else if (!values.Yaxis || !plot.Yaxis || !is(fromJS(values.Yaxis), fromJS(plot.Yaxis))) {
-            _plot.enabled = 'false'
-            _plot.customs = []
-            _plot.colors = null
-          }
-
-          if (values.datatype !== plot.datatype) {
-            _plot.colors = null
-          }
-
-          this.setState({
-            plot: _plot,
-            visible: false
-          })
-
-          this.props.plotchange({...config, plot: _plot})
-        }
-      })
-    } else if (view === 'base') {
+    if (view === 'base') {
       this.baseRef.handleConfirm().then(res => {
         let _plot = {...plot, ...res}
 
@@ -500,66 +61,9 @@
   }
 
   changeTab = (tab) => {
-    const { config } = this.props
     const { plot, view } = this.state
 
-    if (view === 'normal') {
-      this.props.form.validateFieldsAndScroll((err, values) => {
-        if (!err) {
-          let _plot = {...plot, ...values}
-
-          if (values.datatype === 'statistics' || values.datatype !== plot.datatype) {
-            _plot.enabled = 'false'
-            _plot.customs = []
-          } else if (!values.Yaxis || !plot.Yaxis || !is(fromJS(values.Yaxis), fromJS(plot.Yaxis))) {
-            _plot.enabled = 'false'
-            _plot.customs = []
-            _plot.colors = null
-          }
-
-          let labels = {}
-          config.columns.forEach(col => {
-            labels[col.field] = col.label
-          })
-
-          if (values.datatype !== 'statistics' && (!_plot.customs || _plot.customs.length === 0)) {
-            _plot.customs = _plot.Yaxis.map((item, i) => {
-              return {
-                uuid: Utils.getuuid(),
-                type: item,
-                name: labels[item] || item,
-                axis: i === 0 ? 'true' : 'false',
-                label: 'false',
-                title: 'true',
-                shape: _plot.chartType === 'bar' && i === 0 ? ['bar', 'rect'] : ['line', 'smooth']
-              }
-            })
-          }
-          if (values.datatype !== plot.datatype || !_plot.colors) {
-            _plot.colors = []
-            if (_plot.datatype === 'query') {
-              let limit = chartColors.length
-
-              _plot.colors = _plot.Yaxis.map((item, i) => {
-                return {
-                  uuid: Utils.getuuid(),
-                  type: item,
-                  label: labels[item] || item,
-                  color: chartColors[i % limit],
-                  color1: chartColors[i % limit]
-                }
-              })
-            }
-          }
-
-          this.setState({
-            datatype: _plot.datatype,
-            plot: _plot,
-            view: tab
-          })
-        }
-      })
-    } else if (view === 'base') {
+    if (view === 'base') {
       this.baseRef.handleConfirm().then(res => {
         this.setState({
           plot: {...plot, ...res},
@@ -573,50 +77,22 @@
     }
   }
 
-  addColor = () => {
-    let plot = fromJS(this.state.plot).toJS()
-    plot.colors = plot.colors || []
+  onChange = (val) => {
+    const { plot } = this.state
 
-    plot.colors.push({
-      uuid: Utils.getuuid(),
-      type: `鎸囨爣${plot.colors.length}`,
-      color: 'rgb(91, 143, 249)',
-      color1: 'rgb(91, 143, 249)'
+    this.setState({
+      plot: {...plot, script: val},
     })
-
-    this.setState({plot})
-  }
-
-  changeColor = (colors) => {
-    const { plot } = this.state
-
-    this.setState({plot: {...plot, colors}})
-  }
-
-  changeCustom = (customs) => {
-    const { plot } = this.state
-
-    this.setState({plot: {...plot, customs}})
   }
 
   render() {
-    const { view, visible, datatype, plot, ramp, colorColumns, rampColorColumns, statColorColumns, rampStatColorColumns, cusColumns, baseFormlist } = this.state
-    const formItemLayout = {
-      labelCol: {
-        xs: { span: 24 },
-        sm: { span: 6 }
-      },
-      wrapperCol: {
-        xs: { span: 24 },
-        sm: { span: 18 }
-      }
-    }
+    const { view, visible, baseFormlist, plot } = this.state
 
     return (
-      <div className="line-chart-drawer-form">
-        <Icon type="edit" title="缂栬緫" onClick={this.showDrawer} />
+      <>
+        <Icon type="edit" style={{color: '#1890ff'}} title="缂栬緫" onClick={this.showDrawer} />
         <Modal
-          wrapClassName="popview-modal menu-chart-edit-modal"
+          wrapClassName="popview-modal custom-chart-edit-modal"
           title="鍥捐〃缂栬緫"
           visible={visible}
           width={950}
@@ -625,72 +101,19 @@
           onCancel={() => { this.setState({ visible: false }) }}
           destroyOnClose
         >
-          <Tabs activeKey={view} className="menu-chart-edit-box" onChange={this.changeTab}>
+          <Tabs activeKey={view} onChange={this.changeTab}>
             <TabPane tab="缁勪欢璁剧疆" key="base">
               <NormalForm dict={this.props.dict} formlist={baseFormlist} inputSubmit={this.onSubmit} wrappedComponentRef={(inst) => this.baseRef = inst}/>
             </TabPane>
-            <TabPane tab="鍥捐〃璁剧疆" key="normal">
-              <Form {...formItemLayout}>
-                <Row gutter={16}>{this.getFields()}</Row>
-              </Form>
-            </TabPane>
-            {plot ? <TabPane tab="棰滆壊璁剧疆" key="color">
-              <div>
-                <Col span={8} style={{height: '40px', top: '-5px', zIndex: 1}}>
-                  <Form {...formItemLayout}>
-                    <Form.Item label="娓愬彉鑹�" style={{marginBottom: 10}}>
-                      <Radio.Group value={plot.ramp || 'false'} onChange={this.rampChange}>
-                        <Radio value="false">涓嶄娇鐢�</Radio>
-                        <Radio value="true">浣跨敤</Radio>
-                      </Radio.Group>
-                    </Form.Item>
-                  </Form>
-                </Col>
-                {plot.chartType === 'line' ? <Col span={8} style={{height: '40px', top: '-5px', zIndex: 1}}>
-                  <Form {...formItemLayout}>
-                    <Form.Item label="娓愬彉鏂瑰悜" style={{marginBottom: 10}}>
-                      <Radio.Group value={plot.rampDirection || 'horizontal'} onChange={this.rampDirectionChange}>
-                        <Radio value="horizontal">姘村钩</Radio>
-                        <Radio value="vertical">鍨傜洿</Radio>
-                      </Radio.Group>
-                    </Form.Item>
-                  </Form>
-                </Col> : null}
-                {datatype === 'statistics' ? <Button className="color-add mk-green" onClick={this.addColor}>{this.props.dict['model.add']}</Button> : null}
-                {datatype === 'statistics' ? <EditTable actions={['edit', 'move', 'del']} data={plot.colors || []} columns={ramp ==='true' ? rampStatColorColumns : statColorColumns} onChange={this.changeColor}/> : null}
-                {datatype !== 'statistics' ? <EditTable actions={['edit']} data={plot.colors || []} columns={ramp ==='true' ? rampColorColumns : colorColumns} onChange={this.changeColor}/> : null}
-              </div>
-            </TabPane> : null}
-            {plot ? <TabPane tab="鑷畾涔夎缃�" disabled={datatype === 'statistics'} key="custom">
-              <Col span={12}>
-                <Form {...formItemLayout}>
-                  <Form.Item label="鏄惁鍚敤" style={{marginBottom: 10}}>
-                    <Radio.Group value={plot.enabled || 'false'} onChange={this.enabledChange}>
-                      <Radio value="true">鏄�</Radio>
-                      <Radio value="false">鍚�</Radio>
-                    </Radio.Group>
-                  </Form.Item>
-                </Form>
-              </Col>
-              <Col span={12}>
-                <Form {...formItemLayout}>
-                  <Form.Item label="澶氭煴鎺掑垪" style={{marginBottom: 10}}>
-                    <Radio.Group value={plot.mutilBar || 'dodge'} onChange={this.mutilBarChange}>
-                      <Radio value="dodge">鍒嗙粍</Radio>
-                      <Radio value="stack">鍫嗗彔</Radio>
-                      <Radio value="overlap">閲嶅彔</Radio>
-                    </Radio.Group>
-                  </Form.Item>
-                </Form>
-              </Col>
-              <Col style={{fontSize: '12px', color: '#757575', paddingLeft: '10px'}} span={24}>娉細浣跨敤鑷畾涔夎缃椂锛屾樉绀虹殑鍧愭爣杞寸涓�涓湪宸︿晶锛岀浜屼釜鍦ㄥ彸渚э紝澶氫綑鐨勪笉鐢熸晥銆�</Col>
-              <EditTable actions={['edit', 'move']} data={plot.customs || []} columns={cusColumns} onChange={this.changeCustom}/>
+            {plot ? <TabPane tab="JS" key="JS">
+              {plot.chartType === 'antv' ? <div>鍏ュ弬锛欳hart銆� DataSet銆� wrap锛坉om鑺傜偣锛夈�乨ata銆� config</div> : <div>鍏ュ弬锛歟charts銆� DataSet銆� wrap锛坉om鑺傜偣锛夈�� data銆� config</div>}
+              <CodeMirror mode="text/javascript" theme="cobalt" value={plot.script} onChange={this.onChange} />
             </TabPane> : null}
           </Tabs>
         </Modal>
-      </div>
+      </>
     );
   }
 }
 
-export default Form.create()(LineChartDrawerForm)
\ No newline at end of file
+export default Form.create()(CustomChartDrawerForm)
\ No newline at end of file
diff --git a/src/menu/components/chart/chart-custom/chartcompile/index.scss b/src/menu/components/chart/chart-custom/chartcompile/index.scss
index 244c6aa..9e19200 100644
--- a/src/menu/components/chart/chart-custom/chartcompile/index.scss
+++ b/src/menu/components/chart/chart-custom/chartcompile/index.scss
@@ -1,43 +1,10 @@
-.line-chart-drawer-form {
-  display: inline-block;
-  > .anticon-edit {
-    color: #1890ff;
-  }
-}
-.menu-chart-edit-modal {
+.custom-chart-edit-modal {
   .ant-modal {
     top: 50px;
     .ant-modal-body {
       max-height: calc(100vh - 190px);
       min-height: 50vh;
       padding-top: 10px;
-      .menu-chart-edit-box {
-        .anticon-question-circle {
-          color: #c49f47;
-          position: relative;
-          left: -3px;
-        }
-        .ant-input-number {
-          width: 100%;
-        }
-        .ant-radio-wrapper {
-          margin-right: 5px;
-        }
-        .ant-tabs-nav-wrap {
-          text-align: center;
-        }
-        .color-sketch-block {
-          position: relative;
-          top: 5px;
-          width: 240px;
-        }
-        .color-add {
-          float: right;
-          margin-bottom: 10px;
-          position: relative;
-          z-index: 1;
-        }
-      }
     }
   }
 }
diff --git a/src/menu/components/chart/chart-custom/index.jsx b/src/menu/components/chart/chart-custom/index.jsx
index 467f90b..386c7fc 100644
--- a/src/menu/components/chart/chart-custom/index.jsx
+++ b/src/menu/components/chart/chart-custom/index.jsx
@@ -1,16 +1,16 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Icon, Popover } from 'antd'
+import { Icon, Popover, notification } from 'antd'
 import { Chart } from '@antv/g2'
 import DataSet from '@antv/data-set'
+import * as echarts from 'echarts'
 
 import MKEmitter from '@/utils/events.js'
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
 import { resetStyle } from '@/utils/utils-custom.js'
 import Utils from '@/utils/utils.js'
-import { chartColors } from '@/utils/option.js'
 import zhCN from '@/locales/zh-CN/model.js'
 import enUS from '@/locales/en-US/model.js'
 import './index.scss'
@@ -18,10 +18,7 @@
 const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
 const ChartCompileForm = asyncIconComponent(() => import('./chartcompile'))
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
-const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
 const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
-const ActionComponent = asyncComponent(() => import('@/menu/components/share/actioncomponent'))
-const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
 const ClockComponent = asyncIconComponent(() => import('@/menu/components/share/clockcomponent'))
 
 class ChartCustom extends Component {
@@ -42,17 +39,12 @@
 
     if (card.isNew) {
       let _plot = {
-        chartType: card.type, // 鍥捐〃绫诲瀷
-        enabled: 'false',     // 鏄惁浣跨敤鑷畾涔夎缃�
-        datatype: 'query',    // 鏁版嵁绫诲瀷鏌ヨ鎴栫粺璁�
-        customs: [],
+        chartType: 'antv', // 鍥捐〃绫诲瀷
         width: card.width || 24,
         height: 400,
-        barSize: 35,
-        color: 'rgba(0, 0, 0, 0.65)',
-        name: card.name
+        name: card.name,
+        script: ''
       }
-
 
       let _card = {
         uuid: card.uuid,
@@ -89,10 +81,6 @@
         _card.style = config.style
         _card.headerStyle = config.headerStyle
 
-        _card.action = config.action.map(col => {
-          col.uuid = Utils.getuuid()
-          return col
-        })
         _card.search = config.search.map(col => {
           col.uuid = Utils.getuuid()
           return col
@@ -139,6 +127,8 @@
       let _element = document.getElementById(card.uuid + 'canvas')
       if (_element) {
         _element.innerHTML = ''
+        _element.removeAttribute('_echarts_instance_')
+        _element.removeAttribute('style')
       }
 
       this.$timer && clearTimeout(this.$timer)
@@ -146,1050 +136,39 @@
     }
   }
 
-  getdata = (X_axis, Y_axis) => {
-    let data = []
-    let xdata = ['鍛ㄤ竴', '鍛ㄤ簩', '鍛ㄤ笁', '鍛ㄥ洓', '鍛ㄤ簲', '鍛ㄥ叚', '鍛ㄦ棩']
-    let point = 7
-
-    for (let i = 0; i < point; i++) {
-      let item = {}
-
-      item[X_axis] = xdata[i]
-
-      if (typeof(Y_axis) === 'string') {
-        item[Y_axis] = Math.floor(Math.random() * 5 * (i + 1)) + i
-      } else {
-        Y_axis.forEach(y => {
-          item[y] = Math.floor(Math.random() * 5 * (i + 1)) + i
-        })
-      }
-
-      data.push(item)
-    }
-
-    return data
-  }
-
   viewrender = () => {
     const { card } = this.state
 
-    if (card.plot.chartType === 'line') {
-      this.linerender()
-    } else if (card.plot.chartType === 'bar') {
-      this.barrender()
-    }
-  }
+    if (!card.plot.script) return
 
-  /**
-   * @description 鎶樼嚎鍥�
-   */
-  linerender = () => {
-    const { card } = this.state
-    const plot = card.plot
-    let color = plot.color || 'rgba(0, 0, 0, 0.65)'
-    let X_axis = plot.Xaxis || 'x'
-    let Y_axis = plot.Yaxis || ['y']
-
-    let data = this.getdata(X_axis, Y_axis)
-
-    if (plot.enabled !== 'true') {
-      const ds = new DataSet()
-      const dv = ds.createView().source(data)
-      let transfield = {}
-      card.columns.forEach(col => {
-        if (col.field) {
-          transfield[col.field] = col.label
-        }
-      })
-
-      dv.transform({
-        type: 'fold',
-        fields: [...Y_axis],
-        key: 'key',
-        value: 'value'
-      })
-
-      if (plot.Xaxis) {
-        dv.transform({
-          type: 'map',
-          callback(row) {
-            row.key = transfield[row.key] || row.key
-            return row
-          },
+    if (card.plot.chartType === 'antv') {
+      try {
+        // eslint-disable-next-line
+        let func = new Function('Chart', 'DataSet', 'wrap', 'data', 'config', card.plot.script)
+        func(Chart, DataSet, this.wrap, [], card)
+      } catch (e) {
+        console.warn(e)
+  
+        notification.warning({
+          top: 92,
+          message: '鍥捐〃娓叉煋澶辫触锛�',
+          duration: 5
         })
       }
-
-      const chart = new Chart({
-        container: card.uuid + 'canvas',
-        autoFit: true,
-        height: this.wrap.offsetHeight - 25
-      })
+    } else if (card.plot.chartType === 'echarts') {
+      try {
+        // eslint-disable-next-line
+        let func = new Function('echarts', 'DataSet', 'wrap', 'data', 'config', card.plot.script)
+        func(echarts, DataSet, this.wrap, [], card)
+      } catch (e) {
+        console.warn(e)
   
-      chart.data(dv.rows)
-
-      // chart.axis(X_axis, { label: { style: { fill: color } }, tickLine: {style: { stroke: color }}, line: { style: { stroke: color } } })
-      // chart.axis('value', { grid: { line: { style: { stroke: color } }}, label: { style: { fill: color } } })
-
-      let xc = {label: { style: { fill: color } }}
-      let yc = {label: { style: { fill: color } }}
-      if (plot.grid === 'hidden') {
-        yc.grid = null
-      }
-      if (plot.y_line === 'show') {
-        yc.line = {style: { stroke: '#D1D2CE' }}
-      }
-      if (plot.lineColor) {
-        xc.tickLine = {style: { stroke: plot.lineColor }}
-        xc.line = { style: { stroke: plot.lineColor } }
-        if (yc.grid !== null) {
-          yc.grid = { line: { style: { stroke: plot.lineColor } }}
-        }
-        if (yc.line) {
-          yc.line = { style: { stroke: plot.lineColor } }
-        }
-      }
-      chart.axis(X_axis, xc)
-      chart.axis('value', yc)
-  
-      if (plot.coordinate !== 'polar') {
-        chart.scale(X_axis, {
-          range: [0, 1]
+        notification.warning({
+          top: 92,
+          message: '鍥捐〃娓叉煋澶辫触锛�',
+          duration: 5
         })
       }
-      chart.scale('value', {
-        nice: true,
-        range: [0, 0.9]
-      })
-  
-      if (!plot.legend || plot.legend === 'hidden') {
-        chart.legend(false)
-      } else {
-        chart.legend({
-          position: plot.legend,
-          itemName: { style: { fill: color } }
-        })
-      }
-  
-      if (plot.tooltip !== 'true') {
-        chart.tooltip(false)
-      } else {
-        chart.tooltip({
-          shared: true
-        })
-      }
-  
-      if (plot.transpose === 'true') {
-        chart.coordinate().transpose()
-      }
-  
-      if (plot.coordinate === 'polar') {
-        chart.coordinate('polar', {
-          innerRadius: 0.1,
-          radius: 0.8
-        })
-      }
-
-      let colors = new Map()
-      let colorIndex = 0
-
-      if (plot.colors && plot.colors.length > 0) {
-        if (plot.ramp === 'true') {
-          let _s = 'l(0) '
-          if (plot.rampDirection === 'vertical') {
-            _s = 'l(90) '
-          }
-          plot.colors.forEach(item => {
-            if (!colors.has(transfield[item.type])) {
-              colors.set(transfield[item.type], `${_s}0:${item.color} 1:${item.color1}` )
-            }
-          })
-        } else {
-          plot.colors.forEach(item => {
-            if (!colors.has(transfield[item.type])) {
-              colors.set(transfield[item.type], item.color)
-            }
-          })
-        }
-      }
-  
-      let _chart = chart
-        .line()
-        .position(`${X_axis}*value`)
-        .shape(plot.shape || 'smooth')
-        .tooltip(`${X_axis}*value*key`, (name, value, type) => {
-          if (plot.show === 'percent') {
-            value = value + '%'
-          }
-          return {
-            name: type,
-            value: value
-          }
-        })
-  
-      if (plot.colors && plot.colors.length > 0) {
-        let limit = chartColors.length
-        _chart.color('key', (key) => {
-          if (colors.has(key)) {
-            if (plot.area === 'true' && plot.rampDirection === 'vertical') {
-              return colors.get(key).replace(/l\(9?0\) 0:|\s1:.*/ig, '')
-            }
-            return colors.get(key)
-          } else {
-            colorIndex++
-            return chartColors[(colorIndex - 1) % limit]
-          }
-        })
-      } else {
-        _chart.color('key')
-      }
-      if (plot.label !== 'false') {
-        _chart.label('value*key', (value, key) => {
-          if (plot.show === 'percent') {
-            value = value + '%'
-          }
-          let _color = color
-
-          if (plot.labelColor === 'custom' && colors.has(key)) {
-            _color = colors.get(key)
-          }
-          return {
-            content: value,
-            style: {
-              fill: _color
-            }
-          }
-        })
-      }
-
-      if (plot.point === 'true') {
-        chart
-          .point()
-          .position(`${X_axis}*value`)
-          .color('key')
-          .size(3)
-          .shape('circle')
-      }
-
-      if (plot.area === 'true') {
-        let area = chart.area().position(`${X_axis}*value`).tooltip(false)
-        if (plot.shape === 'smooth') {
-          area.shape('smooth')
-        }
-        if (plot.colors && plot.colors.length > 0) {
-          let limit = chartColors.length
-          area.color('key', (key) => {
-            if (colors.has(key)) {
-              return colors.get(key)
-            } else {
-              colorIndex++
-              return chartColors[(colorIndex - 1) % limit]
-            }
-          })
-        } else {
-          area.color('key')
-        }
-      }
-
-      if (plot.interaction && plot.interaction.length) {
-        plot.interaction.forEach(t => {
-          chart.interaction(t)
-        })
-      }
-      chart.render()
-    } else {
-      this.customrender(data)
-    }
-  }
-
-  /**
-   * @description 鑷畾涔夊浘
-   */
-  customrender = (data) => {
-    let card = fromJS(this.state.card).toJS()
-    let plot = card.plot
-    let color = plot.color || 'rgba(0, 0, 0, 0.65)'
-    let fields = []
-    let legends = []
-    let transfield = {}
-    let Bar_axis = []
-
-    card.columns.forEach(col => {
-      if (col.field) {
-        transfield[col.field] = col.label
-      }
-    })
-
-    let colors = new Map()
-    let colorIndex = 0
-    let limit = chartColors.length
-
-    if (plot.colors && plot.colors.length > 0) {
-      if (plot.ramp === 'true') {
-        let bars = {}
-        plot.customs.forEach(item => {
-          if (!item.shape || !item.shape[0] || item.shape[0] === 'bar') {
-            bars[item.type] = true
-          }
-        })
-        plot.colors.forEach(item => {
-          if (!colors.has(transfield[item.type])) {
-            if (bars[item.type]) {
-              colors.set(transfield[item.type], `l(90) 0:${item.color} 1:${item.color1}` )
-            } else {
-              colors.set(transfield[item.type], `l(0) 0:${item.color} 1:${item.color1}` )
-            }
-          }
-        })
-      } else {
-        plot.colors.forEach(item => {
-          if (!colors.has(transfield[item.type])) {
-            colors.set(transfield[item.type], item.color)
-          }
-        })
-      }
-    }
-
-    let axisIndex = 0
-    let hasBar = false
-
-    plot.$paddingLeft = 30
-    plot.$paddingRight = 30
-
-    plot.customs.forEach(item => {
-      item.name = transfield[item.type] || item.type
-      item.chartType = item.shape ? (item.shape[0] || 'bar') : 'bar'
-      item.shape = item.shape ? (item.shape[1] || '') : ''
-
-      if (colors.has(item.name)) {
-        item.color = colors.get(item.name)
-      } else {
-        item.color = chartColors[colorIndex % limit]
-        colorIndex++
-      }
-
-      if (item.chartType === 'bar') {
-        Bar_axis.push(item.type)
-        hasBar = true
-      }
-
-      if (item.axis === 'true' && axisIndex < 2) {
-        if (axisIndex === 0) {
-          // item.axis = { grid: {line: { style: { stroke: color } }}, title: { style: { fill: color } }, label: {style: { fill: color }} }
-          item.axis = { label: {style: { fill: color }} }
-          if (item.title !== 'false') {
-            item.axis.title = { style: { fill: color } }
-            plot.$paddingLeft = 50
-          }
-          if (plot.grid === 'hidden') {
-            item.axis.grid = null
-          }
-          if (plot.y_line === 'show') {
-            item.axis.line = {style: { stroke: '#D1D2CE' }}
-          }
-          if (plot.lineColor) {
-            if (item.axis.grid !== null) {
-              item.axis.grid = { line: { style: { stroke: plot.lineColor } }}
-            }
-            if (item.axis.line) {
-              item.axis.line = { style: { stroke: plot.lineColor } }
-            }
-          }
-          
-          fields.unshift(item)
-        } else {
-          item.axis = { grid: null, label: {style: { fill: color }} }
-          if (item.title !== 'false') {
-            item.axis.title = { style: { fill: color } }
-            plot.$paddingRight = 60
-          }
-          if (plot.y_line === 'show') {
-            item.axis.line = {style: { stroke: '#D1D2CE' }}
-          }
-          if (plot.lineColor && item.axis.line) {
-            item.axis.line = { style: { stroke: plot.lineColor } }
-          }
-          fields.splice(1, 0, item)
-        }
-        axisIndex++
-      } else {
-        item.axis = { grid: null, title: null, label: null }
-        fields.push(item)
-      }
-      
-      legends.push({
-        value: item.name,
-        name: item.name,
-        marker: { symbol: item.chartType === 'bar' ? 'square' : 'hyphen', style: { stroke: item.color,fill: item.color, r: 5, lineWidth: 2 } }
-      })
-    })
-
-    const ds = new DataSet()
-    const dv = ds.createView().source(data)
-    dv.transform({
-      type: 'map',
-      callback(row) {
-        fields.forEach(line => {
-          row[line.name] = row[line.type]
-        })
-        return row
-      }
-    })
-
-    let padding = [10, 30, 30, 30]
-    if (plot.mutilBar === 'overlap') {
-      Bar_axis = []
-    }
-
-    if (!Bar_axis.length) {
-      padding = [10, plot.$paddingRight, 30, plot.$paddingLeft]
-    }
-
-    const chart = new Chart({
-      container: card.uuid + 'canvas',
-      autoFit: true,
-      height: this.wrap.offsetHeight - 25,
-    })
-
-    // chart.axis(plot.Xaxis, { label: { style: { fill: color } }, tickLine: {style: { stroke: color }}, line: { style: { stroke: color } } })
-
-    let xc = {label: { style: { fill: color } }}
-    if (plot.lineColor) {
-      xc.tickLine = {style: { stroke: plot.lineColor }}
-      xc.line = { style: { stroke: plot.lineColor } }
-    }
-    chart.axis(plot.Xaxis, xc)
-
-    if (!hasBar) {
-      chart.scale(plot.Xaxis, {
-        range: [0, 1]
-      })
-    }
-
-    if (!plot.legend || plot.legend === 'hidden') {
-      chart.legend(false)
-    } else {
-      chart.legend({
-        custom: true,
-        position: plot.legend,
-        items: legends,
-        itemName: { style: { fill: color } }
-      })
-    }
-
-    if (plot.tooltip !== 'true') {
-      chart.tooltip(false)
-    } else {
-      chart.tooltip({
-        shared: true,
-      })
-    }
-
-    chart.scale({
-      nice: true
-    })
-
-    let lablecfg = {
-      position: 'top',
-      offset: 2,
-      style: {
-        fill: '#fff'
-      }
-    }
-
-    if (plot.label === 'top') {
-      lablecfg.offset = -5
-      lablecfg.style.textBaseline = 'top'
-    } else if (plot.label === 'middle') {
-      lablecfg.position = 'middle'
-      lablecfg.offset = 0
-    } else if (plot.label === 'bottom') {
-      lablecfg.position = 'bottom'
-      lablecfg.offset = 0
-    } else if (plot.label === 'true') {
-      lablecfg.style.fill = color
-    }
-    
-    if (Bar_axis.length) {
-      const view1 = chart.createView({
-        region: {
-          start: { x: 0, y: 0 },
-          end: { x: 1, y: 1 }
-        },
-        padding
-      })
-      const dst = new DataSet()
-      const dvt = dst.createView().source(data)
-  
-      dvt.transform({
-        type: 'fold',
-        fields: [...Bar_axis],
-        key: 'key',
-        value: 'value'
-      })
-  
-      dvt.transform({
-        type: 'map',
-        callback(row) {
-          row.key = transfield[row.key] || row.key
-          return row
-        },
-      })
-
-      view1.data(dvt.rows)
-      view1.scale('value', {
-        nice: true,
-        range: [0, 0.9]
-      })
-
-      let yc = {label: { style: { fill: color } }}
-      if (plot.grid === 'hidden') {
-        yc.grid = null
-      }
-      if (plot.y_line === 'show') {
-        yc.line = {style: { stroke: '#D1D2CE' }}
-      }
-      if (plot.lineColor) {
-        if (yc.grid !== null) {
-          yc.grid = { line: { style: { stroke: plot.lineColor } }}
-        }
-        if (yc.line) {
-          yc.line = { style: { stroke: plot.lineColor } }
-        }
-      }
-      view1.axis('value', yc)
-  
-      view1.legend(false)
-  
-      if (plot.mutilBar !== 'stack') {
-        let _chart = view1
-          .interval()
-          .position(`${plot.Xaxis}*value`)
-          .adjust([
-            {
-              type: 'dodge',
-              marginRatio: 0
-            }
-          ])
-          .shape(plot.shape || 'rect')
-          .tooltip(`${plot.Xaxis}*value*key`, (name, value, key) => {
-            if (plot.show === 'percent') {
-              value = value + '%'
-            }
-            return {
-              name: key,
-              value: value
-            }
-          })
-
-        if (plot.colors && plot.colors.length > 0) {
-          let limit = chartColors.length
-          _chart.color('key', (key) => {
-            if (colors.has(key)) {
-              return colors.get(key)
-            } else {
-              colorIndex++
-              return chartColors[(colorIndex - 1) % limit]
-            }
-          })
-        } else {
-          _chart.color('key')
-        }
-        if (plot.label !== 'false') {
-          _chart.label('value*key', (value, key) => {
-            if (plot.show === 'percent') {
-              value = value + '%'
-            }
-
-            if (plot.label === 'true' && plot.labelColor === 'custom' && colors.has(key)) {
-              lablecfg.style.fill = colors.get(key)
-            }
-            return {
-              content: value,
-              ...lablecfg
-            }
-          })
-        }
-
-        if (plot.barSize || plot.correction) {
-          _chart.size(plot.barSize || 35)
-        }
-        if (plot.barRadius) {
-          _chart.style({ radius: [plot.barRadius, plot.barRadius, 0, 0] })
-        }
-      } else if (plot.mutilBar === 'stack') {
-        let _chart = view1
-          .interval()
-          .position(`${plot.Xaxis}*value`)
-          .adjust('stack')
-          .shape(plot.shape || 'rect')
-          .tooltip(`${plot.Xaxis}*value*key`, (name, value, type) => {
-            if (plot.show === 'percent') {
-              value = value + '%'
-            }
-            return {
-              name: type,
-              value: value
-            }
-          })
-  
-        if (plot.colors && plot.colors.length > 0) {
-          let limit = chartColors.length
-          _chart.color('key', (key) => {
-            if (colors.has(key)) {
-              return colors.get(key)
-            } else {
-              colorIndex++
-              return chartColors[(colorIndex - 1) % limit]
-            }
-          })
-        } else {
-          _chart.color('key')
-        }
-        if (plot.label !== 'false') {
-          _chart.label('value*key', (value, key) => {
-            if (plot.show === 'percent') {
-              value = value + '%'
-            }
-
-            if (plot.label === 'true' && plot.labelColor === 'custom' && colors.has(key)) {
-              lablecfg.style.fill = colors.get(key)
-            }
-
-            return {
-              content: value,
-              ...lablecfg
-            }
-          })
-        }
-
-        if (plot.barSize || plot.correction) {
-          _chart.size(plot.barSize || 35)
-        }
-        if (plot.barRadius) {
-          _chart.style({ radius: [plot.barRadius, plot.barRadius, 0, 0] })
-        }
-      }
-    }
-
-    const view2 = chart.createView({
-      region: {
-        start: { x: 0, y: 0 },
-        end: { x: 1, y: 1 }
-      },
-      padding
-    })
-
-    view2.data(dv.rows)
-
-    view2.legend(false)
-
-    fields.forEach(item => {
-      if (item.chartType === 'bar' && !Bar_axis.length) {
-        view2.axis(item.name, item.axis)
-      
-        view2.scale(item.name, {
-          nice: true,
-          range: [0, 0.9]
-        })
-
-        let _chart = view2
-          .interval()
-          .position(`${plot.Xaxis}*${item.name}`)
-          .color(item.color)
-          .shape(item.shape)
-          .tooltip(`${item.name}`, (value) => {
-            if (plot.show === 'percent') {
-              value = value + '%'
-            }
-            return {
-              name: item.name,
-              value: value
-            }
-          })
-
-        if (plot.barSize) {
-          _chart.size(plot.barSize || 35)
-        }
-        if (item.label !== 'false') {
-          _chart.label(item.name, (value) => {
-            if (plot.show === 'percent') {
-              value = value + '%'
-            }
-
-            if (plot.label === 'true' && plot.labelColor === 'custom') {
-              lablecfg.style.fill = item.color
-            }
-            return {
-              content: value,
-              ...lablecfg
-            }
-          })
-        }
-        if (plot.barRadius) {
-          _chart.style({ radius: [plot.barRadius, plot.barRadius, 0, 0] })
-        }
-      } else if (item.chartType === 'line') {
-        if (!Bar_axis.length) {
-          view2.axis(item.name, item.axis)
-        } else {
-          view2.axis(item.name, { grid: null, title: null, label: null })
-        }
-        view2.scale(item.name, {
-          nice: true,
-          range: [0, 0.9]
-        })
-        let _chart = view2
-          .line()
-          .position(`${plot.Xaxis}*${item.name}`)
-          .color(item.color)
-          .shape(item.shape)
-          .tooltip(`${item.name}`, (value) => {
-            if (plot.show === 'percent') {
-              value = value + '%'
-            }
-            return {
-              name: item.name,
-              value: value
-            }
-          })
-
-        if (item.label !== 'false') {
-          _chart.label(item.name, (value) => {
-            if (plot.show === 'percent') {
-              value = value + '%'
-            }
-            let _color = color
-
-            if (plot.labelColor === 'custom') {
-              _color = item.color
-            }
-            return {
-              content: value,
-              style: {
-                fill: _color
-              }
-            }
-          })
-        }
-
-        if (plot.point === 'true') {
-          chart
-            .point()
-            .position(`${plot.Xaxis}*${item.name}`)
-            .color(item.color)
-            .size(3)
-            .shape('circle')
-        }
-      }
-    })
-
-    if (plot.interaction && plot.interaction.length) {
-      plot.interaction.forEach(t => {
-        if (t === 'element-active' || t === 'element-highlight') {
-          chart.interaction(t)
-        }
-      })
-    }
-
-    chart.render()
-  }
-
-  /**
-   * @description 鏌卞舰鍥�
-   */
-  barrender = () => {
-    const { card } = this.state
-    const plot = card.plot
-    let color = plot.color || 'rgba(0, 0, 0, 0.65)'
-    let X_axis = plot.Xaxis || 'x'
-    let Y_axis = plot.Yaxis || ['y']
-
-    let data = this.getdata(X_axis, Y_axis)
-    
-    if (plot.enabled !== 'true') {
-      const ds = new DataSet()
-      const dv = ds.createView().source(data)
-      let transfield = {}
-
-      card.columns.forEach(col => {
-        if (col.field) {
-          transfield[col.field] = col.label
-        }
-      })
-  
-      dv.transform({
-        type: 'fold',
-        fields: [...Y_axis],
-        key: 'key',
-        value: 'value'
-      })
-  
-      if (plot.Xaxis) {
-        dv.transform({
-          type: 'map',
-          callback(row) {
-            row.key = transfield[row.key] || row.key
-            return row
-          },
-        })
-      }
-
-      const chart = new Chart({
-        container: card.uuid + 'canvas',
-        autoFit: true,
-        height: this.wrap.offsetHeight - 25
-      })
-
-      chart.data(dv.rows)
-
-      // chart.axis(X_axis, { label: { style: { fill: color } }, tickLine: {style: { stroke: color }}, line: { style: { stroke: color } } })
-      // chart.axis('value', { grid: { line: { style: { stroke: color } }}, label: { style: { fill: color } } })
-
-      let xc = {label: { style: { fill: color } }}
-      let yc = {label: { style: { fill: color } }}
-      if (plot.grid === 'hidden') {
-        yc.grid = null
-      }
-      if (plot.y_line === 'show') {
-        yc.line = {style: { stroke: '#D1D2CE' }}
-      }
-      if (plot.lineColor) {
-        xc.tickLine = {style: { stroke: plot.lineColor }}
-        xc.line = { style: { stroke: plot.lineColor } }
-        if (yc.grid !== null) {
-          yc.grid = { line: { style: { stroke: plot.lineColor } }}
-        }
-        if (yc.line) {
-          yc.line = { style: { stroke: plot.lineColor } }
-        }
-      }
-      chart.axis(X_axis, xc)
-      chart.axis('value', yc)
-  
-      chart.scale('value', {
-        nice: true,
-        range: [0, 0.9]
-      })
-  
-      if (!plot.legend || plot.legend === 'hidden') {
-        chart.legend(false)
-      } else {
-        chart.legend({
-          position: plot.legend,
-          itemName: { style: { fill: color } }
-        })
-      }
-  
-      if (plot.tooltip !== 'true') {
-        chart.tooltip(false)
-      } else {
-        chart.tooltip({
-          shared: true
-        })
-      }
-  
-      if (plot.coordinate === 'polar') {
-        chart.coordinate('polar', {
-          innerRadius: 0.1,
-          radius: 0.8
-        })
-      }
-
-      let colors = new Map()
-      let colorIndex = 0
-      let lablecfg = {
-        position: 'top',
-        offset: 2,
-        style: {
-          fill: '#fff'
-        }
-      }
-
-      if (plot.label === 'top') {
-        lablecfg.offset = -5
-        lablecfg.style.textBaseline = 'top'
-      } else if (plot.label === 'middle') {
-        lablecfg.position = 'middle'
-        lablecfg.offset = 0
-      } else if (plot.label === 'bottom') {
-        lablecfg.position = 'bottom'
-        lablecfg.offset = 0
-      } else if (plot.label === 'true') {
-        lablecfg.style.fill = color
-      }
-
-      if (plot.transpose === 'true') {
-        chart.coordinate().transpose()
-        if (plot.label === 'top') {
-          delete lablecfg.style.textBaseline
-          lablecfg.position = 'right'
-          lablecfg.offset = -3
-          lablecfg.style.textAlign = 'end'
-        } else if (plot.label === 'middle') {
-          lablecfg.position = 'middle'
-          lablecfg.offset = 0
-        } else if (plot.label === 'bottom') {
-          lablecfg.position = 'left'
-          lablecfg.offset = 2
-        } else if (plot.label === 'true') {
-          lablecfg.position = 'right'
-          lablecfg.offset = 2
-        }
-      }
-
-      if (plot.colors && plot.colors.length > 0) {
-        if (plot.ramp === 'true') {
-          plot.colors.forEach(item => {
-            if (!colors.has(transfield[item.type])) {
-              colors.set(transfield[item.type], `l(90) 0:${item.color} 1:${item.color1}` )
-            }
-          })
-        } else {
-          plot.colors.forEach(item => {
-            if (!colors.has(transfield[item.type])) {
-              colors.set(transfield[item.type], item.color)
-            }
-          })
-        }
-      }
-  
-      if (plot.adjust !== 'stack') {
-        let _chart = chart
-          .interval()
-          .position(`${X_axis}*value`)
-          .adjust([
-            {
-              type: 'dodge',
-              marginRatio: 0
-            }
-          ])
-          .shape(plot.shape || 'rect')
-          .tooltip(`${X_axis}*value*key`, (name, value, key) => {
-            if (plot.show === 'percent') {
-              value = value + '%'
-            }
-            return {
-              name: key,
-              value: value
-            }
-          })
-
-        if (plot.colors && plot.colors.length > 0) {
-          let limit = chartColors.length
-          _chart.color('key', (key) => {
-            if (colors.has(key)) {
-              return colors.get(key)
-            } else {
-              colorIndex++
-              return chartColors[(colorIndex - 1) % limit]
-            }
-          })
-        } else {
-          _chart.color('key')
-        }
-        if (plot.label !== 'false') {
-          _chart.label('value*key', (value, key) => {
-            if (plot.show === 'percent') {
-              value = value + '%'
-            }
-
-            if (plot.label === 'true' && plot.labelColor === 'custom' && colors.has(key)) {
-              lablecfg.style.fill = colors.get(key)
-            }
-            
-            return {
-              content: value,
-              ...lablecfg
-            }
-          })
-        }
-
-        if (plot.barSize || plot.correction) {
-          _chart.size(plot.barSize || 35)
-        }
-        if (plot.selectColor) {
-          _chart.state({
-            selected: {
-              style: {
-                fill: plot.selectColor,
-              }
-            }
-          })
-        }
-        if (plot.barRadius) {
-          _chart.style({ radius: [plot.barRadius, plot.barRadius, 0, 0] })
-        }
-      } else if (plot.adjust === 'stack') {
-        let _chart = chart
-          .interval()
-          .position(`${X_axis}*value`)
-          .adjust('stack')
-          .shape(plot.shape || 'rect')
-          .tooltip(`${X_axis}*value*key`, (name, value, type) => {
-            if (plot.show === 'percent') {
-              value = value + '%'
-            }
-            return {
-              name: type,
-              value: value
-            }
-          })
-  
-        if (plot.colors && plot.colors.length > 0) {
-          let limit = chartColors.length
-          _chart.color('key', (key) => {
-            if (colors.has(key)) {
-              return colors.get(key)
-            } else {
-              colorIndex++
-              return chartColors[(colorIndex - 1) % limit]
-            }
-          })
-        } else {
-          _chart.color('key')
-        }
-        if (plot.label !== 'false') {
-          _chart.label('value*key', (value, key) => {
-            if (plot.show === 'percent') {
-              value = value + '%'
-            }
-
-            if (plot.label === 'true' && plot.labelColor === 'custom' && colors.has(key)) {
-              lablecfg.style.fill = colors.get(key)
-            }
-            return {
-              content: value,
-              ...lablecfg
-            }
-          })
-        }
-
-        if (plot.barSize || plot.correction) {
-          _chart.size(plot.barSize || 35)
-        }
-        if (plot.selectColor) {
-          _chart.state({
-            selected: {
-              style: {
-                fill: plot.selectColor,
-              }
-            }
-          })
-        }
-        if (plot.barRadius) {
-          _chart.style({ radius: [plot.barRadius, plot.barRadius, 0, 0] })
-        }
-      }
-
-      if (plot.interaction && plot.interaction.length) {
-        plot.interaction.forEach(t => {
-          chart.interaction(t)
-        })
-      }
-  
-      chart.render()
-    } else {
-      this.customrender(data)
     }
   }
 
@@ -1199,6 +178,8 @@
       let _element = document.getElementById(card.uuid + 'canvas')
       if (_element) {
         _element.innerHTML = ''
+        _element.removeAttribute('_echarts_instance_')
+        _element.removeAttribute('style')
       }
       this.$timer && clearTimeout(this.$timer)
       this.$timer = setTimeout(() => {
@@ -1236,34 +217,6 @@
     MKEmitter.emit('addSearch', card.uuid, newcard)
   }
 
-  addButton = () => {
-    const { card } = this.state
-
-    let newcard = {}
-    newcard.uuid = Utils.getuuid()
-    newcard.focus = true
-    
-    newcard.label = '瀵煎嚭Excel'
-    newcard.sqlType = ''
-    newcard.Ot = 'requiredSgl'
-    newcard.OpenType = 'excelOut'
-    newcard.icon = 'download'
-    newcard.class = 'dgreen'
-    newcard.intertype = card.setting.interType
-    newcard.innerFunc = card.setting.innerFunc || ''
-    newcard.sysInterface = card.setting.sysInterface || ''
-    newcard.outerFunc = card.setting.outerFunc || ''
-    newcard.interface = card.setting.interface || ''
-    newcard.execSuccess = 'grid'
-    newcard.execError = 'never'
-    newcard.popClose = 'never'
-    newcard.verify = null
-    newcard.show = 'icon'
-
-    // 娉ㄥ唽浜嬩欢-娣诲姞鎸夐挳
-    MKEmitter.emit('addButton', card.uuid, newcard)
-  }
-
   changeStyle = () => {
     const { card } = this.state
 
@@ -1292,17 +245,14 @@
     let _style = resetStyle(card.style)
 
     return (
-      <div className="menu-line-chart-edit-box" style={{..._style, height: card.plot.height || 400}} onClick={this.clickComponent} id={card.uuid}>
+      <div className="menu-custom-chart-edit-box" style={{..._style, height: card.plot.height || 400}} onClick={this.clickComponent} id={card.uuid}>
         <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
           <div className="mk-popover-control">
             {appType !== 'mob' ? <Icon className="plus" title="娣诲姞鎼滅储" onClick={this.addSearch} type="plus-circle" /> : null}
-            {appType !== 'mob' ? <Icon className="plus" title="娣诲姞鎸夐挳" onClick={this.addButton} type="plus-square" /> : null}
             <ChartCompileForm config={card} dict={this.state.dict} plotchange={this.updateComponent}/>
             <CopyComponent type="line" card={card}/>
-            <PasteComponent config={card} options={['action']} updateConfig={this.updateComponent} />
             <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" />
             <ClockComponent config={card} updateConfig={this.updateComponent}/>
-            <UserComponent config={card}/>
             <Icon className="close" title="delete" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
             <SettingComponent config={card} updateConfig={this.updateComponent}/>
           </div>
@@ -1311,11 +261,6 @@
         </Popover>
         {card.plot.title || card.search.length > 0 ? <NormalHeader config={card} updateComponent={this.updateComponent}/> : null}
         <div className="canvas" id={card.uuid + 'canvas'} ref={ref => this.wrap = ref}></div>
-        {appType !== 'mob' ? <ActionComponent
-          type="chart"
-          config={card}
-          updateaction={this.updateComponent}
-        /> : null}
       </div>
     )
   }
diff --git a/src/menu/components/chart/chart-custom/index.scss b/src/menu/components/chart/chart-custom/index.scss
index 19c0e63..cbfba49 100644
--- a/src/menu/components/chart/chart-custom/index.scss
+++ b/src/menu/components/chart/chart-custom/index.scss
@@ -1,4 +1,4 @@
-.menu-line-chart-edit-box {
+.menu-custom-chart-edit-box {
   position: relative;
   box-sizing: border-box;
   background: #ffffff;
@@ -10,7 +10,7 @@
 
   .canvas {
     margin: 0px;
-    padding: 15px 10px 10px;
+    padding: 0px;
     letter-spacing: 0px;
     flex: 1;
   }
@@ -65,7 +65,7 @@
     top: 45px;
   }
 }
-.menu-line-chart-edit-box:hover {
+.menu-custom-chart-edit-box:hover {
   z-index: 1;
   box-shadow: 0px 0px 4px #1890ff;
 }
diff --git a/src/menu/components/group/groupcomponents/card.jsx b/src/menu/components/group/groupcomponents/card.jsx
index cec20ff..9d4c223 100644
--- a/src/menu/components/group/groupcomponents/card.jsx
+++ b/src/menu/components/group/groupcomponents/card.jsx
@@ -21,6 +21,7 @@
 const CarouselPropCard = asyncComponent(() => import('@/menu/components/carousel/prop-card'))
 const Balcony = asyncComponent(() => import('@/menu/components/card/balcony'))
 const CodeSandbox = asyncComponent(() => import('@/menu/components/code/sandbox'))
+const CustomChart = asyncComponent(() => import('@/menu/components/chart/chart-custom'))
 
 const Card = ({ id, card, moveCard, findCard, delCard, updateConfig }) => {
   const originalIndex = findCard(id).index
@@ -90,6 +91,8 @@
       return (<CodeSandbox card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'balcony') {
       return (<Balcony card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
+    } else if (card.type === 'chart') {
+      return (<CustomChart card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     }
   }
 
diff --git a/src/menu/components/group/groupcomponents/index.jsx b/src/menu/components/group/groupcomponents/index.jsx
index 1efe235..c5bed5f 100644
--- a/src/menu/components/group/groupcomponents/index.jsx
+++ b/src/menu/components/group/groupcomponents/index.jsx
@@ -68,6 +68,7 @@
       let name = ''
       let names = {
         bar: '鏌辩姸鍥�',
+        chart: '鍥捐〃',
         line: '鎶樼嚎鍥�',
         tabs: '鏍囩缁�',
         pie: '楗煎浘',
diff --git a/src/menu/components/share/normalform/index.jsx b/src/menu/components/share/normalform/index.jsx
index eec77c9..8bacb22 100644
--- a/src/menu/components/share/normalform/index.jsx
+++ b/src/menu/components/share/normalform/index.jsx
@@ -131,7 +131,7 @@
                   }
                 ]
               })(
-                <Radio.Group disabled={item.readonly} onChange={(e) => this.radioChange(e, item.key)}>
+                <Radio.Group disabled={item.readonly}>
                   {item.options.map(option => {
                     return (
                       <Radio key={option.value} value={option.value}>{option.text}</Radio>
diff --git a/src/menu/components/tabs/tabcomponents/card.jsx b/src/menu/components/tabs/tabcomponents/card.jsx
index e80787f..f33f2cf 100644
--- a/src/menu/components/tabs/tabcomponents/card.jsx
+++ b/src/menu/components/tabs/tabcomponents/card.jsx
@@ -24,6 +24,7 @@
 const NormalGroup = asyncComponent(() => import('@/menu/components/group/normal-group'))
 const BraftEditor = asyncComponent(() => import('@/menu/components/editor/braft-editor'))
 const CodeSandbox = asyncComponent(() => import('@/menu/components/code/sandbox'))
+const CustomChart = asyncComponent(() => import('@/menu/components/chart/chart-custom'))
 
 const Card = ({ id, card, moveCard, findCard, delCard, updateConfig }) => {
   const originalIndex = findCard(id).index
@@ -99,6 +100,8 @@
       return (<CodeSandbox card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'balcony') {
       return (<Balcony card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
+    } else if (card.type === 'chart') {
+      return (<CustomChart card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     }
   }
 
diff --git a/src/menu/components/tabs/tabcomponents/index.jsx b/src/menu/components/tabs/tabcomponents/index.jsx
index 4632448..5b5538d 100644
--- a/src/menu/components/tabs/tabcomponents/index.jsx
+++ b/src/menu/components/tabs/tabcomponents/index.jsx
@@ -96,6 +96,7 @@
       let name = ''
       let names = {
         bar: '鏌辩姸鍥�',
+        chart: '鍥捐〃',
         line: '鎶樼嚎鍥�',
         tabs: '鏍囩缁�',
         pie: '楗煎浘',
diff --git a/src/menu/menushell/card.jsx b/src/menu/menushell/card.jsx
index 8195ed1..6f30721 100644
--- a/src/menu/menushell/card.jsx
+++ b/src/menu/menushell/card.jsx
@@ -24,6 +24,7 @@
 const NormalGroup = asyncComponent(() => import('@/menu/components/group/normal-group'))
 const BraftEditor = asyncComponent(() => import('@/menu/components/editor/braft-editor'))
 const CodeSandbox = asyncComponent(() => import('@/menu/components/code/sandbox'))
+const CustomChart = asyncComponent(() => import('@/menu/components/chart/chart-custom'))
 
 const Card = ({ id, card, moveCard, findCard, delCard, updateConfig }) => {
   const originalIndex = findCard(id).index
@@ -99,6 +100,8 @@
       return (<CodeSandbox card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'balcony') {
       return (<Balcony card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
+    } else if (card.type === 'chart') {
+      return (<CustomChart card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     }
   }
   return (
diff --git a/src/menu/menushell/index.jsx b/src/menu/menushell/index.jsx
index 7e03f6c..8c1e917 100644
--- a/src/menu/menushell/index.jsx
+++ b/src/menu/menushell/index.jsx
@@ -90,6 +90,7 @@
       let name = ''
       let names = {
         bar: '鏌辩姸鍥�',
+        chart: '鍥捐〃',
         line: '鎶樼嚎鍥�',
         tabs: '鏍囩缁�',
         pie: '楗煎浘',
diff --git a/src/menu/modulesource/option.jsx b/src/menu/modulesource/option.jsx
index 20d8b54..3aa6952 100644
--- a/src/menu/modulesource/option.jsx
+++ b/src/menu/modulesource/option.jsx
@@ -22,7 +22,7 @@
 import dashboard from '@/assets/mobimg/dashboard.png'
 import ratioboard from '@/assets/mobimg/ratioboard.png'
 import scatter from '@/assets/mobimg/scatter.png'
-// import chart from '@/assets/mobimg/chart.png'
+import chart from '@/assets/mobimg/chart.png'
 import tree from '@/assets/mobimg/tree.png'
 
 // 缁勪欢閰嶇疆淇℃伅
@@ -51,7 +51,7 @@
   { type: 'menu', url: dashboard, component: 'dashboard', subtype: 'dashboard', title: '浠〃鐩�', width: 12 },
   { type: 'menu', url: ratioboard, component: 'dashboard', subtype: 'ratioboard', title: '鍗犳瘮鍥�', width: 12 },
   { type: 'menu', url: scatter, component: 'scatter', subtype: 'scatter', title: '鏁g偣鍥�', width: 24 },
-  // { type: 'menu', url: chart, component: 'chart', subtype: 'custom', title: '鑷畾涔夊浘琛�', width: 24 },
+  { type: 'menu', url: chart, component: 'chart', subtype: 'custom', title: '鑷畾涔夊浘琛�', width: 24 },
   { type: 'menu', url: Editor, component: 'editor', subtype: 'brafteditor', title: '瀵屾枃鏈�', width: 24 },
   { type: 'menu', url: SandBox, component: 'code', subtype: 'sandbox', title: '鑷畾涔�', width: 24 },
   { type: 'menu', url: group, component: 'group', subtype: 'normalgroup', title: '鍒嗙粍', width: 24, forbid: ['billPrint'] },
diff --git a/src/tabviews/custom/components/chart/custom-chart/index.jsx b/src/tabviews/custom/components/chart/custom-chart/index.jsx
new file mode 100644
index 0000000..d72aae8
--- /dev/null
+++ b/src/tabviews/custom/components/chart/custom-chart/index.jsx
@@ -0,0 +1,382 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { is, fromJS } from 'immutable'
+import { Chart } from '@antv/g2'
+import DataSet from '@antv/data-set'
+import * as echarts from 'echarts'
+import { Spin, Empty, notification } from 'antd'
+import moment from 'moment'
+
+import Api from '@/api'
+import Utils from '@/utils/utils.js'
+import UtilsDM from '@/utils/utils-datamanage.js'
+import MKEmitter from '@/utils/events.js'
+import NormalHeader from '@/tabviews/custom/components/share/normalheader'
+import './index.scss'
+
+class CustomChart extends Component {
+  static propTpyes = {
+    BID: PropTypes.any,              // 鐖剁骇Id
+    data: PropTypes.array,           // 缁熶竴鏌ヨ鏁版嵁
+    config: PropTypes.object,        // 缁勪欢閰嶇疆淇℃伅
+    mainSearch: PropTypes.any,       // 澶栧眰鎼滅储鏉′欢
+    menuType: PropTypes.any,         // 鑿滃崟绫诲瀷
+  }
+
+  state = {
+    BID: '',                   // 涓昏〃ID
+    config: null,              // 鍥捐〃閰嶇疆淇℃伅
+    empty: true,               // 鍥捐〃鏁版嵁涓虹┖
+    loading: false,            // 鏁版嵁鍔犺浇鐘舵��
+    sync: false,               // 鏄惁缁熶竴璇锋眰鏁版嵁
+    plot: null,                // 鍥捐〃璁剧疆
+    data: null,                // 鏁版嵁
+    search: null,              // 鎼滅储鏉′欢
+  }
+
+  UNSAFE_componentWillMount () {
+    const { config, data, initdata, BID } = this.props
+    let _config = fromJS(config).toJS()
+    let _data = null
+    let _sync = config.setting.sync === 'true'
+
+    if (config.setting.sync === 'true' && data) {
+      _data = data[config.dataName] || []
+      _sync = false
+    } else if (config.setting.sync === 'true' && initdata) {
+      _data = initdata || []
+      _sync = false
+    }
+
+    _config.style.height = config.plot.height || 400
+
+    this.setState({
+      config: _config,
+      data: _data,
+      empty: !_data || _data.length === 0,
+      BID: BID || '',
+      arr_field: _config.columns.map(col => col.field).join(','),
+      plot: _config.plot,
+      sync: _sync,
+      search: Utils.initMainSearch(config.search)
+    }, () => {
+      if (config.setting.sync !== 'true' && config.setting.onload === 'true') {
+        this.loadData()
+      } else if (config.setting.sync === 'true' && _data) {
+        this.handleData()
+      }
+    })
+  }
+
+  /**
+   * @description 鍥捐〃鏁版嵁鏇存柊锛屽埛鏂板唴瀹�
+   */
+  UNSAFE_componentWillReceiveProps (nextProps) {
+    const { sync, config } = this.state
+
+    if (sync && !is(fromJS(this.props.data), fromJS(nextProps.data))) {
+      let _data = []
+      if (nextProps.data && nextProps.data[config.dataName]) {
+        _data = nextProps.data[config.dataName] || []
+      }
+
+      this.setState({sync: false, data: _data, empty: _data.length === 0}, () => {
+        this.handleData()
+      })
+    } else if (config.setting.syncRefresh && nextProps.mainSearch && !is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
+      this.setState({}, () => {
+        this.loadData()
+      })
+    }
+  }
+
+  shouldComponentUpdate (nextProps, nextState) {
+    return !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  componentDidMount () {
+    MKEmitter.addListener('reloadData', this.reloadData)
+    MKEmitter.addListener('resetSelectLine', this.resetParentParam)
+    MKEmitter.addListener('queryModuleParam', this.queryModuleParam)
+    MKEmitter.addListener('refreshByButtonResult', this.refreshByButtonResult)
+    this.handleTimer()
+  }
+
+  /**
+   * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊锛屾竻闄ゅ揩鎹烽敭璁剧疆
+   */
+  componentWillUnmount () {
+    clearTimeout(this.timer)
+    this.setState = () => {
+      return
+    }
+    MKEmitter.removeListener('reloadData', this.reloadData)
+    MKEmitter.removeListener('resetSelectLine', this.resetParentParam)
+    MKEmitter.removeListener('queryModuleParam', this.queryModuleParam)
+    MKEmitter.removeListener('refreshByButtonResult', this.refreshByButtonResult)
+  }
+
+  handleTimer = () => {
+    const { config } = this.state
+
+    if (!config.timer) return
+
+    const _change = { '5s': 5000, '15s': 15000, '30s': 30000, '1min': 60000, '5min': 300000, '10min': 600000, '15min': 900000, '30min': 1800000, '1hour': 3600000 }
+
+    let timer = _change[config.timer]
+
+    if (!timer) return
+
+    let _param = {
+      func: 's_get_timers_role',
+      LText: `select '${window.GLOB.appkey || ''}','${config.uuid}'`,
+      timer_type: config.timer,
+      component_id: config.uuid
+    }
+    
+    _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')          // 鏃堕棿鎴�
+    _param.LText = Utils.formatOptions(_param.LText)                   // 鍏抽敭瀛楃鏇挎崲锛宐ase64鍔犲瘑
+    _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp)   // md5瀵嗛挜
+
+    Api.getSystemConfig(_param).then(result => {
+      if (!result.status) {
+        notification.warning({
+          top: 92,
+          message: result.message,
+          duration: 5
+        })
+        return
+      } else if (result.run_type) {
+        this.setState({timer})
+        this.timer = setTimeout(() => {
+          this.timerTask()
+        }, timer)
+      }
+    })
+  }
+
+  timerTask = () => {
+    const { timer } = this.state
+    if (!timer) return
+    
+    this.loadData(true)
+    
+    this.timer = setTimeout(() => {
+      this.timerTask()
+    }, timer)
+  }
+
+  /**
+   * @description 鎸夐挳鎵ц瀹屾垚鍚庨〉闈㈠埛鏂�
+   * @param {*} menuId     // 鑿滃崟Id
+   * @param {*} position   // 鍒锋柊浣嶇疆
+   * @param {*} btn        // 鎵ц鐨勬寜閽�
+   */
+  refreshByButtonResult = (menuId, position, btn) => {
+    const { config, BID } = this.state
+
+    if (config.uuid !== menuId) return
+
+    this.loadData()                                                            // 鏁版嵁鍒锋柊
+
+    if (btn.syncComponentId && btn.syncComponentId !== config.uuid && btn.syncComponentId !== config.setting.supModule) {
+      MKEmitter.emit('reloadData', btn.syncComponentId)                        // 鍚岀骇鏍囩鍒锋柊
+    }
+
+    if (position === 'mainline' && config.setting.supModule) {                 // 涓昏〃琛屽埛鏂�
+      MKEmitter.emit('reloadData', config.setting.supModule, (BID || 'empty'))
+    } else if (position === 'popclose') {                                      // 鏍囩鍏抽棴鍒锋柊
+      config.setting.supModule && MKEmitter.emit('reloadData', config.setting.supModule, (BID || 'empty'))
+      btn.$tabId && MKEmitter.emit('refreshPopButton', btn.$tabId)
+    }
+  }
+
+  reloadData = (menuId) => {
+    const { config } = this.state
+
+    if (config.uuid !== menuId) return
+
+    this.loadData()
+  }
+
+  resetParentParam = (MenuID, id) => {
+    const { config } = this.state
+
+    if (!config.setting.supModule || config.setting.supModule !== MenuID) return
+    if (id !== this.state.BID) {
+      this.setState({ BID: id }, () => {
+        this.loadData()
+      })
+    }
+  }
+
+  /**
+   * @description 瀵煎嚭Excel鏃讹紝鑾峰彇椤甸潰鎼滅储鎺掑簭绛夊弬鏁�
+   */
+  queryModuleParam = (menuId, btnId) => {
+    const { mainSearch } = this.props
+    const { arr_field, config, search } = this.state
+
+    if (config.uuid !== menuId) return
+
+    let searches = search ? fromJS(search).toJS() : []
+    if (config.setting.useMSearch && mainSearch && mainSearch.length > 0) { // 涓昏〃鎼滅储鏉′欢
+      let keys = searches.map(item => item.key.toLowerCase())
+      mainSearch.forEach(item => {
+        if (!keys.includes(item.key.toLowerCase())) {
+          searches.push(item)
+        }
+      })
+    }
+
+    MKEmitter.emit('returnModuleParam', config.uuid, btnId, {
+      arr_field: arr_field,
+      orderBy: config.setting.order || '',
+      search: searches,
+      menuName: config.name
+    })
+  }
+
+  /**
+   * @description 鏁版嵁鍔犺浇
+   */
+  async loadData (hastimer) {
+    const { mainSearch, menuType } = this.props
+    const { config, arr_field, BID, search } = this.state
+
+    if (config.setting.supModule && !BID) { // BID 涓嶅瓨鍦ㄦ椂锛屼笉鍋氭煡璇�
+      this.setState({
+        data: []
+      }, () => {
+        this.handleData()
+      })
+      return
+    }
+
+    let searches = search ? fromJS(search).toJS() : []
+    if (config.setting.useMSearch && mainSearch && mainSearch.length > 0) { // 涓昏〃鎼滅储鏉′欢
+      let keys = searches.map(item => item.key)
+      mainSearch.forEach(item => {
+        if (!keys.includes(item.key)) {
+          searches.push(item)
+        }
+      })
+    }
+
+    let requireFields = searches.filter(item => item.required && item.value === '')
+    if (requireFields.length > 0) {
+      return
+    }
+
+    if (!hastimer) {
+      this.setState({
+        loading: true
+      })
+    }
+
+    let _orderBy = config.setting.order || ''
+    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, '', '', BID, menuType)
+
+    let result = await Api.genericInterface(param)
+    if (result.status) {
+      this.setState({
+        data: result.data,
+        loading: false,
+        empty: result.data.length === 0
+      }, () => {
+        this.handleData()
+      })
+    } else {
+      this.setState({
+        loading: false,
+        timer: null
+      })
+      notification.error({
+        top: 92,
+        message: result.message,
+        duration: 10
+      })
+    }
+  }
+
+  /**
+   * @description 鏁版嵁棰勫鐞嗭紝缁熻鏁版嵁闇�瑕侀噸缃�
+   */
+  handleData = () => {
+    if (!this.wrap) return
+
+    this.wrap.innerHTML = ''
+    this.wrap.removeAttribute('_echarts_instance_')
+    this.wrap.removeAttribute('style')
+    
+    setTimeout(() => {
+      this.viewrender()
+    }, 150)
+  }
+
+  /**
+   * @description 鍥捐〃娓叉煋鍒嗙粍
+   */
+  viewrender = () => {
+    const { config, data } = this.state
+
+    if (!config.plot.script) return
+
+    if (config.plot.chartType === 'antv') {
+      try {
+        // eslint-disable-next-line
+        let func = new Function('Chart', 'DataSet', 'wrap', 'data', 'config', config.plot.script)
+        func(Chart, DataSet, this.wrap, data, config)
+      } catch (e) {
+        console.warn(e)
+  
+        notification.warning({
+          top: 92,
+          message: '鍥捐〃娓叉煋澶辫触锛�',
+          duration: 5
+        })
+      }
+    } else if (config.plot.chartType === 'echarts') {
+      try {
+        // eslint-disable-next-line
+        let func = new Function('echarts', 'DataSet', 'wrap', 'data', 'config', config.plot.script)
+        func(echarts, DataSet, this.wrap, data, config)
+      } catch (e) {
+        console.warn(e)
+  
+        notification.warning({
+          top: 92,
+          message: '鍥捐〃娓叉煋澶辫触锛�',
+          duration: 5
+        })
+      }
+    }
+  }
+
+
+  refreshSearch = (list) => {
+    this.setState({search: list}, () => {
+      this.loadData()
+    })
+  }
+
+  render() {
+    const { config, loading, empty, BID } = this.state
+
+    return (
+      <div className="custom-chart-plot-box" style={config.style}>
+        {loading ?
+          <div className="loading-mask">
+            <div className="ant-spin-blur"></div>
+            <Spin />
+          </div> : null
+        }
+        <NormalHeader config={config} BID={BID} menuType={this.props.menuType} refresh={this.refreshSearch} />
+        <div className={'canvas' + (empty ? ' empty' : '')} ref={ref => this.wrap = ref}></div>
+        {empty ? <Empty description={false}/> : null}
+      </div>
+    )
+  }
+}
+
+export default CustomChart
\ No newline at end of file
diff --git a/src/tabviews/custom/components/chart/custom-chart/index.scss b/src/tabviews/custom/components/chart/custom-chart/index.scss
new file mode 100644
index 0000000..009f7a6
--- /dev/null
+++ b/src/tabviews/custom/components/chart/custom-chart/index.scss
@@ -0,0 +1,57 @@
+.custom-chart-plot-box {
+  position: relative;
+  background: #ffffff;
+  background-position: center center;
+  background-repeat: no-repeat;
+  background-size: cover;
+  min-height: 100px;
+  display: flex;
+  flex-flow: column;
+
+  .canvas {
+    margin: 0;
+    padding: 0px;
+    letter-spacing: 0px;
+    flex: 1;
+  }
+  .canvas.empty {
+    div {
+      opacity: 0;
+    }
+  }
+  .ant-empty {
+    position: absolute;
+    top: calc(50% - 34px);
+    left: calc(50% - 92px);
+
+    .ant-empty-image {
+      height: 60px;
+    }
+  }
+  .loading-mask {
+    position: absolute;
+    left: 0px;
+    top: 0;
+    right: 0px;
+    bottom: 0px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    text-align: justify;
+    z-index: 1;
+
+    .ant-spin-blur {
+      position: absolute;
+      width: 100%;
+      height: 100%;
+      opacity: 0.5;
+      background: #ffffff;
+    }
+  }
+  .g2-tooltip-list{
+    display: none;
+  }
+  .g2-tooltip-title + .g2-tooltip-list{
+    display: block;
+  }
+}
diff --git a/src/tabviews/custom/components/group/normal-group/index.jsx b/src/tabviews/custom/components/group/normal-group/index.jsx
index 0840e45..99486fe 100644
--- a/src/tabviews/custom/components/group/normal-group/index.jsx
+++ b/src/tabviews/custom/components/group/normal-group/index.jsx
@@ -31,6 +31,7 @@
 const CarouselDataCard = asyncComponent(() => import('@/tabviews/custom/components/carousel/data-card'))
 const CarouselPropCard = asyncComponent(() => import('@/tabviews/custom/components/carousel/prop-card'))
 const Balcony = asyncComponent(() => import('@/tabviews/custom/components/card/balcony'))
+const CustomChart = asyncComponent(() => import('@/tabviews/custom/components/chart/custom-chart'))
 
 class TabTransfer extends Component {
   static propTpyes = {
@@ -244,6 +245,12 @@
             <Balcony config={item} data={data} BID={_bid} menuType={menuType} />
           </Col>
         )
+      } else if (item.type === 'chart') {
+        return (
+          <Col span={item.width} key={item.uuid}>
+            <CustomChart config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+          </Col>
+        )
       } else {
         return null
       }
diff --git a/src/tabviews/custom/components/share/tabtransfer/index.jsx b/src/tabviews/custom/components/share/tabtransfer/index.jsx
index 24afb5d..ae8f36b 100644
--- a/src/tabviews/custom/components/share/tabtransfer/index.jsx
+++ b/src/tabviews/custom/components/share/tabtransfer/index.jsx
@@ -34,6 +34,7 @@
 const CarouselDataCard = asyncComponent(() => import('@/tabviews/custom/components/carousel/data-card'))
 const CarouselPropCard = asyncComponent(() => import('@/tabviews/custom/components/carousel/prop-card'))
 const Balcony = asyncComponent(() => import('@/tabviews/custom/components/card/balcony'))
+const CustomChart = asyncComponent(() => import('@/tabviews/custom/components/chart/custom-chart'))
 
 class TabTransfer extends Component {
   static propTpyes = {
@@ -284,6 +285,12 @@
             <Balcony config={item} data={data} BID={BID} menuType={menuType} />
           </Col>
         )
+      } else if (item.type === 'chart') {
+        return (
+          <Col span={item.width} key={item.uuid}>
+            <CustomChart config={item} data={data} BID={BID} mainSearch={mainSearch} menuType={menuType} />
+          </Col>
+        )
       } else {
         return null
       }
diff --git a/src/tabviews/custom/index.jsx b/src/tabviews/custom/index.jsx
index 2ad0982..420caa2 100644
--- a/src/tabviews/custom/index.jsx
+++ b/src/tabviews/custom/index.jsx
@@ -38,6 +38,7 @@
 const Balcony = asyncComponent(() => import('./components/card/balcony'))
 const SettingComponent = asyncComponent(() => import('@/tabviews/zshare/settingcomponent'))
 const PagemsgComponent = asyncComponent(() => import('@/tabviews/zshare/pageMessage'))
+const CustomChart = asyncComponent(() => import('./components/chart/custom-chart'))
 
 class CustomPage extends Component {
   static propTpyes = {
@@ -502,7 +503,7 @@
         }
 
         item.components = this.filterComponent(item.components, roleId, permAction, permMenus, balMap, skip)
-      } else if (['pie', 'bar', 'line', 'dashboard', 'scatter'].includes(item.type)) {
+      } else if (['pie', 'bar', 'line', 'dashboard', 'scatter', 'chart'].includes(item.type)) {
         if (
           item.plot.blacklist && item.plot.blacklist.length > 0 &&
           item.plot.blacklist.filter(v => roleId.indexOf(v) > -1).length > 0
@@ -1144,6 +1145,12 @@
             <SandBox config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
           </Col>
         )
+      } else if (item.type === 'chart') {
+        return (
+          <Col span={item.width} key={item.uuid}>
+            <CustomChart config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+          </Col>
+        )
       } else {
         return null
       }
diff --git a/src/views/menudesign/index.jsx b/src/views/menudesign/index.jsx
index be66c84..2477bd9 100644
--- a/src/views/menudesign/index.jsx
+++ b/src/views/menudesign/index.jsx
@@ -427,7 +427,7 @@
             buttons.push(`select '${cell.uuid}' as menuid, '${item.name + '-' + cell.label}' as menuname, '${_sort * 10}' as Sort`)
             _sort++
           })
-        } else if (item.type === 'line' || item.type === 'bar') {
+        } else if (item.type === 'line' || item.type === 'bar' || item.type === 'chart') {
           item.action && item.action.forEach(btn => {
             this.checkBtn(btn)
             buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`)

--
Gitblit v1.8.0