From 31ec63f0419895876cbaba99637a884a32d33d0d Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期三, 01 九月 2021 10:31:45 +0800
Subject: [PATCH] 2021-09-01

---
 src/tabviews/zshare/chartcomponent/index.jsx |  277 ++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 214 insertions(+), 63 deletions(-)

diff --git a/src/tabviews/zshare/chartcomponent/index.jsx b/src/tabviews/zshare/chartcomponent/index.jsx
index 4837e12..231654d 100644
--- a/src/tabviews/zshare/chartcomponent/index.jsx
+++ b/src/tabviews/zshare/chartcomponent/index.jsx
@@ -5,47 +5,92 @@
 import DataSet from '@antv/data-set'
 import { Spin, Empty, Select } from 'antd'
 
+import asyncComponent from './asyncButtonComponent'
 import Utils from '@/utils/utils.js'
-import zhCN from '@/locales/zh-CN/model.js'
-import enUS from '@/locales/en-US/model.js'
+import zhCN from '@/locales/zh-CN/main.js'
+import enUS from '@/locales/en-US/main.js'
 import './index.scss'
+
+const ExcelOutButton = asyncComponent(() => import('@/tabviews/zshare/actionList/exceloutbutton'))
+const ExcelInButton = asyncComponent(() => import('@/tabviews/zshare/actionList/excelInbutton'))
 
 class LineChart extends Component {
   static propTpyes = {
-    plot: PropTypes.object,
-    data: PropTypes.array,
-    loading: PropTypes.bool,
-    config: PropTypes.object
+    BID: PropTypes.any,              // 鐖剁骇Id
+    Tab: PropTypes.any,              // 鏍囩淇℃伅
+    plot: PropTypes.object,          // 鍥炬爣璁剧疆淇℃伅
+    data: PropTypes.array,           // 鍥捐〃浼犲叆鏁版嵁
+    loading: PropTypes.bool,         // 鏁版嵁鍔犺浇涓�
+    config: PropTypes.object,        // 椤甸潰閰嶇疆淇℃伅
   }
 
   state = {
-    dict: (!localStorage.getItem('lang') || localStorage.getItem('lang') === 'zh-CN') ? zhCN : enUS,
-    empty: true,
-    chartId: Utils.getuuid(),
-    chartData: [],
-    chartFields: [],
-    selectFields: []
+    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, // 瀛楀吀
+    empty: true,               // 鍥捐〃鏁版嵁涓虹┖
+    actions: [],               // 鍥捐〃缁戝畾鐨勬寜閽粍
+    chartId: Utils.getuuid(),  // 鍥捐〃Id
+    chartData: [],             // 鍥捐〃鏁版嵁
+    chartFields: [],           // 缁熻鍥捐〃鐢熸垚瀛楁闆�
+    selectFields: [],          // 缁熻鍥捐〃閫夋嫨瀛楁
+    percentFields: []          // 璁剧疆涓虹櫨鍒嗘瘮鐨勫瓧娈碉紝tooltip鏃跺鍔�%
   }
 
+  /**
+   * @description 鏍¢獙鍥捐〃鐨勬寜閽粍锛屽鏋滀负缁熻鍥捐〃锛岃绠楀浘琛ㄥ瓧娈�
+   */
   componentDidMount () {
-    const { plot, data } = this.props
-
+    const { plot, data, config } = this.props
     let _state = {}
+    let actions = []
+    let percentFields = []
+
+    config.action.forEach(item => {
+      if (!plot.actions || plot.actions.length === 0) return
+      if (!(item.OpenType === 'excelOut' || (item.OpenType === 'excelIn' && item.Ot === 'notRequired'))) return
+      if (plot.actions.includes(item.uuid)) {
+        actions.push(fromJS(item).toJS())
+      }
+    })
 
     if (plot.datatype === 'statistics' && (plot.chartType === 'line' || plot.chartType === 'bar')) {
       let result = this.getStaticMsg(data)
       _state.chartData = result.data
       _state.chartFields = result.chartFields
       _state.selectFields = result.selectFields
+      _state.actions = actions
+
+      let _column = config.columns.filter(col => plot.InfoValue === col.field)[0]
+
+      if (_column && _column.format === 'percent') {
+        percentFields.push(plot.InfoValue)
+        _state.percentFields = percentFields
+      }
 
       this.setState(_state, () => {
         this.viewrender()
       })
     } else {
-      this.viewrender()
+      if (plot.chartType === 'line' || plot.chartType === 'bar') {
+        try {
+          plot.Yaxis.forEach(yaxis => {
+            let _column = config.columns.filter(col => yaxis === col.field)[0]
+            if (_column && _column.format === 'percent') {
+              percentFields.push(_column.label)
+            }
+          })
+        } catch (e) {
+          console.warn('Incorrect percentage setting')
+        }
+      }
+      this.setState({ actions, percentFields }, () => {
+        this.viewrender()
+      })
     }
   }
 
+  /**
+   * @description 鍥捐〃鏁版嵁鏇存柊锛屽埛鏂板唴瀹�
+   */
   UNSAFE_componentWillReceiveProps (nextProps) {
     const { plot } = this.props
     if (!is(fromJS(this.props.data), fromJS(nextProps.data))) {
@@ -72,9 +117,14 @@
     return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
   }
 
+  /**
+   * @description 鍥捐〃鏁版嵁棰勫鐞�
+   * 1銆侀�氳繃鏄剧ず鍒楄繘琛屾暟鎹被鍨嬭浆鎹�
+   * 2銆侀噸澶嶆暟鎹細鍙栧钩鍧囧�笺�佺疮璁°�佸幓閲�
+   * 3銆佹煴鐘跺浘鏁版嵁琛ラ綈
+   */
   getdata = () => {
     const { data, plot, config } = this.props
-    
     let vFields = plot.Yaxis && typeof(plot.Yaxis) === 'string' ? [plot.Yaxis] : plot.Yaxis
     let _columns = config.columns.filter(col => vFields.includes(col.field))
 
@@ -181,26 +231,13 @@
       _data = [..._mdata.values()]
     }
 
-    if (plot.correction && plot.chartType === 'bar' && _data.length > 0 && _data.length < plot.correction) {
-      if (plot.enabled !== 'true' || (plot.customs && plot.customs.filter(cell => cell.chartType !== 'bar').length === 0)) {
-        let _num = plot.correction - _data.length
-        for (let i = 0; i < _num; i++) {
-          let _val = Array( i + 2 ).join(' ')
-          let _cell = {}
-          _cell[plot.Xaxis] = _val
-          _columns.forEach(col => {
-            _cell[col.field] = ''
-          })
-  
-          _data.push(_cell)
-        }
-      }
-    }
-
     this.setState({empty: _data.length === 0})
     return _data
   }
 
+  /**
+   * @description 缁熻鏁版嵁棰勫鐞嗭紝鍔ㄦ�佺敓鎴愮粺璁″瓧娈靛苟杩涜鏁版嵁杞崲
+   */
   getStaticMsg = (data) => {
     const { plot, config } = this.props
 
@@ -232,7 +269,7 @@
 
         item.$uuid = item[plot.InfoType] + item[plot.Xaxis]
         if (typeof(item[plot.InfoValue]) !== 'number') {
-          item[plot.InfoValue] = parseFloat(plot.InfoValue)
+          item[plot.InfoValue] = parseFloat(item[plot.InfoValue])
           if (isNaN(item[plot.InfoValue])) {
             item[plot.InfoValue] = 0
           }
@@ -269,7 +306,7 @@
         item.$uuid = item[plot.InfoType] + item[plot.Xaxis]
 
         if (typeof(item[plot.InfoValue]) !== 'number') {
-          item[plot.InfoValue] = parseFloat(plot.InfoValue)
+          item[plot.InfoValue] = parseFloat(item[plot.InfoValue])
           if (isNaN(item[plot.InfoValue])) {
             item[plot.InfoValue] = 0
           }
@@ -304,7 +341,7 @@
 
         if (!_mdata.has(item.$uuid)) {
           if (typeof(item[plot.InfoValue]) !== 'number') {
-            item[plot.InfoValue] = parseFloat(plot.InfoValue)
+            item[plot.InfoValue] = parseFloat(item[plot.InfoValue])
             if (isNaN(item[plot.InfoValue])) {
               item[plot.InfoValue] = 0
             }
@@ -334,6 +371,9 @@
     return {data: _data, chartFields: _chartFields, selectFields: _selectFields}
   }
 
+  /**
+   * @description 鑾峰彇缁熻鍥捐〃灞曠ず鏁版嵁锛岄�氳繃閫夋嫨绫诲瀷绛涢��
+   */
   getStaticData = () => {
     const { plot } = this.props
     const { chartData, chartFields, selectFields } = this.state
@@ -349,6 +389,9 @@
     return _data
   }
 
+  /**
+   * @description 鍥捐〃娓叉煋鍒嗙粍
+   */
   viewrender = () => {
     const { plot } = this.props
 
@@ -361,16 +404,25 @@
     }
   }
 
+  /**
+   * @description 鎶樼嚎鍥炬覆鏌�
+   */
   linerender = () => {
     const { plot, config } = this.props
+    const { percentFields } = this.state
 
     let _data = []
     let _valfield = 'value'
     let _typefield = 'key'
+    let ispercent = false
 
     if (plot.datatype === 'statistics') {
       _valfield = plot.InfoValue
       _typefield = plot.InfoType
+
+      if (percentFields.length > 0) {
+        ispercent = true
+      }
 
       _data = this.getStaticData()
     } else {
@@ -426,7 +478,8 @@
       })
     }
     chart.scale(_valfield, {
-      nice: true
+      nice: true,
+      range: [0, 0.93]
     })
 
     // 鍧愭爣杞存牸寮忓寲
@@ -435,8 +488,8 @@
         formatter: (val) => {
           if (!val || /^\s*$/.test(val)) return val
           let _val = `${val}`
-          if (_val.length <= 10) return val
-          return _val.substring(0, 5) + '...'
+          if (_val.length <= 11) return val
+          return _val.substring(0, 8) + '...'
         }
       }
     })
@@ -473,6 +526,12 @@
       .position(`${plot.Xaxis}*${_valfield}`)
       .color(_typefield)
       .shape(plot.shape || 'smooth')
+      .tooltip(`${plot.Xaxis}*${_valfield}*${_typefield}`, (name, value, type) => {
+        return {
+          name: type,
+          value: percentFields.includes(type) || ispercent ? value + '%' : value
+        }
+      })
 
     if (plot.label === 'true') {
       _chart.label(_valfield)
@@ -490,8 +549,12 @@
     chart.render()
   }
 
+  /**
+   * @description 鑷畾涔夋覆鏌�
+   */
   customrender = (data, transfield) => {
     const { plot } = this.props
+    const { percentFields } = this.state
 
     let barfields = []
     let fields = []
@@ -559,8 +622,8 @@
         formatter: (val) => {
           if (!val || /^\s*$/.test(val)) return val
           let _val = `${val}`
-          if (_val.length <= 10) return val
-          return _val.substring(0, 5) + '...'
+          if (_val.length <= 11) return val
+          return _val.substring(0, 8) + '...'
         }
       }
     })
@@ -614,13 +677,19 @@
           label: null
         })
       }
-      
+
       if (item.chartType === 'bar') {
         let _chart = chart
           .interval()
           .position(`${plot.Xaxis}*${item.name}`)
           .color(item.color)
           .shape(item.shape)
+          .tooltip(`${item.name}`, (value) => {
+            return {
+              name: item.name,
+              value: percentFields.includes(item.name) ? value + '%' : value
+            }
+          })
 
         if (item.label === 'true') {
           _chart.label(item.name)
@@ -631,6 +700,12 @@
           .position(`${plot.Xaxis}*${item.name}`)
           .color(item.color)
           .shape(item.shape)
+          .tooltip(`${item.name}`, (value) => {
+            return {
+              name: item.name,
+              value: percentFields.includes(item.name) ? value + '%' : value
+            }
+          })
 
         if (item.label === 'true') {
           _chart.label(item.name)
@@ -650,16 +725,25 @@
     chart.render()
   }
 
+  /**
+   * @description 鏌辩姸鍥炬覆鏌�
+   */
   barrender = () => {
     const { plot, config } = this.props
+    const { percentFields } = this.state
 
     let _data = []
     let _valfield = 'value'
     let _typefield = 'key'
+    let ispercent = false
 
     if (plot.datatype === 'statistics') {
       _valfield = plot.InfoValue
       _typefield = plot.InfoType
+
+      if (percentFields.length > 0) {
+        ispercent = true
+      }
 
       _data = this.getStaticData()
     } else {
@@ -708,13 +792,21 @@
 
     // dodge is not support linear attribute, please use category attribute! 鏃堕棿鏍煎紡
     if (_data[0] && _data[0][plot.Xaxis] && /^\d{4}-\d{2}-\d{2}(\s\d{2}:\d{2}:\d{2})?/.test(_data[0][plot.Xaxis])) {
+      for (let i = 1; i < 12; i++) {
+        if (_data[i] && _data[i][plot.Xaxis] === _data[0][plot.Xaxis]) {
+          _data[i][plot.Xaxis] += ' '
+        } else {
+          break;
+        }
+      }
       _data[0][plot.Xaxis] += ' '
     }
 
     chart.data(_data)
 
     chart.scale(_valfield, {
-      nice: true
+      nice: true,
+      range: [0, 0.93]
     })
 
     // 鍧愭爣杞存牸寮忓寲
@@ -723,8 +815,8 @@
         formatter: (val) => {
           if (!val || /^\s*$/.test(val)) return val
           let _val = `${val}`
-          if (_val.length <= 10) return val
-          return _val.substring(0, 5) + '...'
+          if (_val.length <= 11) return val
+          return _val.substring(0, 8) + '...'
         }
       }
     })
@@ -761,6 +853,7 @@
       let _chart = chart
         .interval()
         .position(`${plot.Xaxis}*${_valfield}`)
+        .size(30)
         .color(_typefield)
         .adjust([
           {
@@ -769,6 +862,12 @@
           }
         ])
         .shape(plot.shape || 'rect')
+        .tooltip(`${plot.Xaxis}*${_valfield}*${_typefield}`, (name, value, type) => {
+          return {
+            name: type,
+            value: percentFields.includes(type) || ispercent ? value + '%' : value
+          }
+        })
 
       if (plot.label === 'true') {
         _chart.label(_valfield)
@@ -777,9 +876,16 @@
       let _chart = chart
         .interval()
         .position(`${plot.Xaxis}*${_valfield}`)
+        .size(30)
         .color(_typefield)
         .adjust('stack')
         .shape(plot.shape || 'rect')
+        .tooltip(`${plot.Xaxis}*${_valfield}*${_typefield}`, (name, value, type) => {
+          return {
+            name: type,
+            value: percentFields.includes(type) || ispercent ? value + '%' : value
+          }
+        })
 
       if (plot.label === 'true') {
         _chart.label(_valfield)
@@ -789,6 +895,9 @@
     chart.render()
   }
 
+  /**
+   * @description 楗煎浘娓叉煋
+   */
   pierender = () => {
     const { plot, config } = this.props
 
@@ -870,24 +979,27 @@
           }
         })
 
-      if (plot.label === 'true') {
-        let setting = {
+      if (plot.label !== 'false') {
+        _chart.label('percent', {
+          layout: { type: 'pie-spider' },
+          labelHeight: 20,
           content: (data) => {
-            return `${data[plot.Xaxis]}: ${(data.percent * 100).toFixed(2)}%`
+            let val = data[plot.Xaxis]
+            if (val) {
+              val = `${val}`
+              if (val.length > 10) {
+                val = val.substring(0, 7) + '...'
+              }
+            }
+            return `${val}: ${(data.percent * 100).toFixed(2)}%`
+          },
+          labelLine: {
+            style: {
+              lineWidth: 0.5,
+            },
           }
-        }
-
-        if (plot.labelLayout === 'overlap') {
-          setting.type = 'pie'
-          setting.layout = {
-            type: 'overlap'
-          }
-          setting.offset = 0
-        }
-
-        _chart.label('percent', setting)
+        })
       }
-      
     } else {
       let _chart = chart
         .interval()
@@ -904,7 +1016,14 @@
       if (plot.label === 'true') {
         let setting = {
           content: (data) => {
-            return `${data[plot.Xaxis]}: ${data[plot.Yaxis]}`
+            let val = data[plot.Xaxis]
+            if (val) {
+              val = `${val}`
+              if (val.length > 10) {
+                val = val.substring(0, 7) + '...'
+              }
+            }
+            return `${val}: ${data[plot.Yaxis]}`
           }
         }
 
@@ -923,6 +1042,9 @@
     chart.render()
   }
 
+  /**
+   * @description 缁熻鍥捐〃锛岀粺璁$被鍨嬪垏鎹�
+   */
   handleChange = (val) => {
     this.setState({selectFields: val}, () => {
       let _element = document.getElementById(this.state.chartId)
@@ -934,8 +1056,8 @@
   }
 
   render() {
-    const { plot, loading } = this.props
-    const { empty, chartFields, selectFields } = this.state
+    const { plot, loading, config, BID, Tab } = this.props
+    const { empty, chartFields, selectFields, actions } = this.state
 
     return (
       <div className="line-chart-plot-box">
@@ -957,7 +1079,36 @@
         >
           {chartFields.map((item, i) => <Select.Option key={i} value={item}>{item}</Select.Option>)}
         </Select> : null}
-        <div className={'canvas' + (empty ? ' empty' : '')} style={{minHeight: plot.height ? plot.height : 400}} id={this.state.chartId}></div>
+        <div className="canvas-wrap">
+          <div className={'chart-action ' + (plot.title ? 'with-title' : '')}>
+            {actions.map(item => {
+              if (item.OpenType === 'excelOut') {
+                return (
+                  <ExcelOutButton
+                    key={item.uuid}
+                    BID={BID}
+                    Tab={Tab}
+                    btn={item}
+                    show="icon"
+                    setting={config.setting}
+                  />
+                )
+              } else {
+                return (
+                  <ExcelInButton
+                    key={item.uuid}
+                    BID={BID}
+                    Tab={Tab}
+                    btn={item}
+                    show="icon"
+                    setting={config.setting}
+                  />
+                )
+              }
+            })}
+          </div>
+          <div className={'canvas' + (empty ? ' empty' : '')} style={{minHeight: plot.height ? plot.height : 400}} id={this.state.chartId}></div>
+        </div>
         {empty ? <Empty description={false}/> : null}
       </div>
     )

--
Gitblit v1.8.0