From abe942f4c6d49a6ad42acaf8e74f5f02b5ffc089 Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期五, 04 六月 2021 15:26:17 +0800
Subject: [PATCH] 2021-06-04

---
 src/tabviews/custom/components/chart/antv-pie/index.jsx |  404 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 368 insertions(+), 36 deletions(-)

diff --git a/src/tabviews/custom/components/chart/antv-pie/index.jsx b/src/tabviews/custom/components/chart/antv-pie/index.jsx
index c398a77..717b6d7 100644
--- a/src/tabviews/custom/components/chart/antv-pie/index.jsx
+++ b/src/tabviews/custom/components/chart/antv-pie/index.jsx
@@ -3,7 +3,7 @@
 import { is, fromJS } from 'immutable'
 import { Chart } from '@antv/g2'
 import { connect } from 'react-redux'
-import DataSet from '@antv/data-set'
+import DataSet, { DataView } from '@antv/data-set'
 import { Spin, Empty, notification } from 'antd'
 import moment from 'moment'
 
@@ -63,6 +63,15 @@
     }
 
     _config.style.height = height
+
+    let decimal = 0
+    _config.columns.forEach(col => {
+      if (_config.plot.Yaxis === col.field && /Decimal/ig.test(col.datatype)) {
+        decimal = +col.datatype.replace(/^Decimal\(18,/ig, '').replace(/\)/ig, '')
+      }
+    })
+
+    _config.plot.$decimal = decimal
 
     this.setState({
       config: _config,
@@ -273,19 +282,12 @@
    * 3銆佹煴鐘跺浘鏁版嵁琛ラ綈
    */
   getdata = () => {
-    const { data, plot, config } = this.state
+    const { data, plot } = this.state
 
     if (!data) {
       this.setState({empty: true})
       return []
     }
-
-    let decimal = 0
-    config.columns.forEach(col => {
-      if (plot.Yaxis === col.field && /Decimal/ig.test(col.datatype)) {
-        decimal = +col.datatype.replace(/^Decimal\(18,/ig, '').replace(/\)/ig, '')
-      }
-    })
 
     let _data = []
     let _cdata = fromJS(data).toJS()
@@ -296,14 +298,16 @@
         if (typeof(item[plot.Yaxis]) !== 'number') {
           item[plot.Yaxis] = parseFloat(item[plot.Yaxis])
           if (isNaN(item[plot.Yaxis])) {
-            item[plot.Yaxis] = 0
+            return
           }
+        } else if (!item[plot.Xaxis]) {
+          return
         }
 
-        if (item[plot.Xaxis] && !_mdata.has(item[plot.Xaxis])) {
+        if (!_mdata.has(item[plot.Xaxis])) {
           item.$count = 1
           _mdata.set(item[plot.Xaxis], item)
-        } else if (item[plot.Xaxis]) {
+        } else {
           let _item = _mdata.get(item[plot.Xaxis])
           _item.$count++
           _item[plot.Yaxis] += item[plot.Yaxis]
@@ -314,8 +318,7 @@
       _data = [..._mdata.values()]
       _data = _data.map(item => {
         item[plot.Yaxis] = item[plot.Yaxis] / item.$count
-        item[plot.Yaxis] = item[plot.Yaxis].toFixed(decimal)
-        item[plot.Yaxis] = +item[plot.Yaxis]
+        item[plot.Yaxis] = +item[plot.Yaxis].toFixed(plot.$decimal)
 
         return item
       })
@@ -325,13 +328,15 @@
         if (typeof(item[plot.Yaxis]) !== 'number') {
           item[plot.Yaxis] = parseFloat(item[plot.Yaxis])
           if (isNaN(item[plot.Yaxis])) {
-            item[plot.Yaxis] = 0
+            return
           }
+        } else if (!item[plot.Xaxis]) {
+          return
         }
 
-        if (item[plot.Xaxis] && !_mdata.has(item[plot.Xaxis])) {
+        if (!_mdata.has(item[plot.Xaxis])) {
           _mdata.set(item[plot.Xaxis], item)
-        } else if (item[plot.Xaxis]) {
+        } else {
           let _item = _mdata.get(item[plot.Xaxis])
           _item[plot.Yaxis] += item[plot.Yaxis]
           _mdata.set(item[plot.Xaxis], _item)
@@ -340,34 +345,355 @@
 
       _data = [..._mdata.values()]
       _data = _data.map(item => {
-        item[plot.Yaxis] = item[plot.Yaxis].toFixed(decimal)
-        item[plot.Yaxis] = +item[plot.Yaxis]
+        item[plot.Yaxis] = +item[plot.Yaxis].toFixed(plot.$decimal)
         return item
       })
     } else { // plot.repeat === 'unrepeat'
       let _mdata = new Map()
       _cdata.forEach(item => {
-        if (item[plot.Xaxis] && !_mdata.has(item[plot.Xaxis])) {
-          
-          if (typeof(item[plot.Yaxis]) !== 'number') {
-            item[plot.Yaxis] = parseFloat(item[plot.Yaxis])
-            if (isNaN(item[plot.Yaxis])) {
-              item[plot.Yaxis] = 0
-            }
-          }
-
-          item[plot.Yaxis] = item[plot.Yaxis].toFixed(decimal)
-          item[plot.Yaxis] = +item[plot.Yaxis]
-
-          _mdata.set(item[plot.Xaxis], item)
+        if (!item[plot.Xaxis] || _mdata.has(item[plot.Xaxis])) {
+          return
         }
+        if (typeof(item[plot.Yaxis]) !== 'number') {
+          item[plot.Yaxis] = parseFloat(item[plot.Yaxis])
+          if (isNaN(item[plot.Yaxis])) {
+            return
+          }
+        }
+
+        item[plot.Yaxis] = +item[plot.Yaxis].toFixed(plot.$decimal)
+
+        _mdata.set(item[plot.Xaxis], item)
       })
 
       _data = [..._mdata.values()]
     }
 
     this.setState({empty: _data.length === 0})
+
     return _data
+  }
+
+  getnestdata = () => {
+    const { data, plot } = this.state
+
+    if (!data) {
+      this.setState({empty: true})
+      return []
+    }
+
+    let _data = []
+    let _cdata = fromJS(data).toJS()
+
+    if (plot.repeat === 'average') {
+      let _mdata = new Map()
+      let map = new Map()
+      let sort = 1
+      _cdata.forEach(item => {
+        if (typeof(item[plot.Yaxis]) !== 'number') {
+          item[plot.Yaxis] = parseFloat(item[plot.Yaxis])
+          if (isNaN(item[plot.Yaxis])) {
+            return
+          }
+        } else if (!item[plot.Xaxis] || !item[plot.type]) {
+          return
+        }
+
+        let sign = item[plot.type] + item[plot.Xaxis]
+
+        if (!_mdata.has(sign)) {
+          let _sort = sort
+          if (map.has(item.type)) {
+            _sort = map.get(item.type)
+          } else {
+            map.set(item.type, _sort)
+            sort++
+          }
+
+          item.$count = 1
+          item.$sort = _sort
+          _mdata.set(sign, item)
+        } else {
+          let _item = _mdata.get(sign)
+          _item.$count++
+          _item[plot.Yaxis] += item[plot.Yaxis]
+          _mdata.set(sign, _item)
+        }
+      })
+
+      _data = [..._mdata.values()]
+      _data = _data.map(item => {
+        item[plot.Yaxis] = item[plot.Yaxis] / item.$count
+        item[plot.Yaxis] = +item[plot.Yaxis].toFixed(plot.$decimal)
+
+        return item
+      })
+    } else if (plot.repeat === 'cumsum') {
+      let _mdata = new Map()
+      let map = new Map()
+      let sort = 1
+      _cdata.forEach(item => {
+        if (typeof(item[plot.Yaxis]) !== 'number') {
+          item[plot.Yaxis] = parseFloat(item[plot.Yaxis])
+          if (isNaN(item[plot.Yaxis])) {
+            return
+          }
+        } else if (!item[plot.Xaxis] || !item[plot.type]) {
+          return
+        }
+
+        let sign = item[plot.type] + item[plot.Xaxis]
+
+        if (!_mdata.has(sign)) {
+          let _sort = sort
+          if (map.has(item.type)) {
+            _sort = map.get(item.type)
+          } else {
+            map.set(item.type, _sort)
+            sort++
+          }
+
+          item.$sort = _sort
+          _mdata.set(sign, item)
+        } else {
+          let _item = _mdata.get(sign)
+          _item[plot.Yaxis] += item[plot.Yaxis]
+          _mdata.set(sign, _item)
+        }
+      })
+
+      _data = [..._mdata.values()]
+      _data = _data.map(item => {
+        item[plot.Yaxis] = +item[plot.Yaxis].toFixed(plot.$decimal)
+        return item
+      })
+    } else { // plot.repeat === 'unrepeat'
+      let _mdata = new Map()
+      let map = new Map()
+      let sort = 1
+      _cdata.forEach(item => {
+        let sign = item[plot.type] + item[plot.Xaxis]
+        if (!item[plot.Xaxis] || !item[plot.type] || _mdata.has(sign)) {
+          return
+        }
+
+        if (typeof(item[plot.Yaxis]) !== 'number') {
+          item[plot.Yaxis] = parseFloat(item[plot.Yaxis])
+          if (isNaN(item[plot.Yaxis])) {
+            return
+          }
+        }
+
+        let _sort = sort
+        if (map.has(item.type)) {
+          _sort = map.get(item.type)
+        } else {
+          map.set(item.type, _sort)
+          sort++
+        }
+
+        item.$sort = _sort
+        item[plot.Yaxis] = +item[plot.Yaxis].toFixed(plot.$decimal)
+
+        _mdata.set(sign, item)
+      })
+
+      _data = [..._mdata.values()]
+    }
+
+    this.setState({empty: _data.length === 0})
+
+    return _data
+  }
+
+  nestrender = () => {
+    const { plot, chartId } = this.state
+
+    let X_axis = plot.Xaxis
+    let Y_axis = plot.Yaxis
+    let type = plot.type
+    let color = plot.color
+
+    let _data = this.getnestdata()
+
+    const dvx = new DataView().source(_data)
+
+    dvx.transform({
+      type: 'sort-by',
+      fields: ['$sort']
+    })
+
+    let data = dvx.rows
+
+    // 閫氳繃 DataSet 璁$畻鐧惧垎姣�
+    const dv = new DataView()
+    dv.source(data).transform({
+      type: 'percent',
+      field: Y_axis,
+      dimension: type,
+      as: '$percent'
+    })
+
+    const dv1 = new DataView()
+    dv1.source(data).transform({
+      type: 'percent',
+      field: Y_axis,
+      dimension: X_axis,
+      as: '$percent',
+    })
+
+    const chart = new Chart({
+      container: chartId,
+      autoFit: true,
+      height: plot.height,
+      padding: 0,
+    })
+
+    chart.data(dv.rows)
+
+    if (plot.show !== 'value') {
+      chart.scale('percent', {
+        formatter: (val) => {
+          val = val * 100 + '%'
+          return val
+        }
+      })
+
+      Y_axis = '$percent'
+    }
+    let radius = plot.radius / 100
+    let innerRadius = plot.innerRadius / 100
+    
+    chart.coordinate('theta', {
+      innerRadius: innerRadius,
+      radius: innerRadius + (radius - innerRadius) / 2,
+    })
+    chart.tooltip({
+      showTitle: false,
+      showMarkers: false,
+    })
+    chart.legend(false)
+    let chart1 = chart
+      .interval()
+      .adjust('stack')
+      .position(Y_axis)
+      .color(type)
+      .tooltip(`${type}*${Y_axis}`, (type, percent) => {
+        if (plot.show !== 'value') {
+          percent = (percent * 100).toFixed(2) + '%'
+        }
+        return {
+          name: type,
+          value: percent,
+        }
+      })
+      .style({
+        lineWidth: 1,
+        stroke: '#fff',
+      })
+
+    if (plot.label !== 'false') {
+      chart1.label(type, {
+        offset: -10,
+      })
+    }
+    
+    const outterView = chart.createView()
+    
+    outterView.data(dv1.rows)
+
+    if (plot.show !== 'value') {
+      outterView.scale('percent', {
+        formatter: (val) => {
+          val = val * 100 + '%'
+          return val
+        }
+      })
+    }
+    outterView.coordinate('theta', {
+      innerRadius: (innerRadius + (radius - innerRadius) / 2) / radius,
+      radius: radius
+    })
+    let chart2 = outterView
+      .interval()
+      .adjust('stack')
+      .position(Y_axis)
+      .color(X_axis)
+      .tooltip(`${X_axis}*${Y_axis}`, (name, value) => {
+        if (plot.show !== 'value') {
+          value = (value * 100).toFixed(2) + '%'
+        }
+        return {
+          name: name,
+          value: value
+        }
+      })
+      .style({
+        lineWidth: 1,
+        stroke: '#fff',
+      })
+
+      if (plot.label !== 'false') {
+        if (plot.label === 'inner') {
+          chart2.label(Y_axis, {
+            offset: -30,
+            content: (data) => {
+              let _label = ''
+              let _val = ''
+              if (plot.show !== 'value') {
+                _val = `${(data[Y_axis] * 100).toFixed(2)}%`
+              } else {
+                _val = `${data[Y_axis]}`
+              }
+              if (plot.label === 'inner') {
+                _label = _val
+              } else {
+                _label = `${data[X_axis]}: ${_val}`
+              }
+              return _label
+            },
+            style: {
+              textAlign: 'center',
+              fontSize: 16,
+              shadowBlur: 2,
+              shadowColor: 'rgba(0, 0, 0, .45)',
+              fill: '#fff',
+            }
+          })
+        } else {
+          chart2.label(Y_axis, {
+            layout: { type: 'pie-spider' },
+            labelHeight: 20,
+            content: (data) => {
+              let _label = ''
+              let _val = ''
+              if (plot.show !== 'value') {
+                _val = `${(data[Y_axis] * 100).toFixed(2)}%`
+              } else {
+                _val = `${data[Y_axis]}`
+              }
+              if (plot.label === 'inner') {
+                _label = _val
+              } else {
+                _label = `${data[X_axis]}: ${_val}`
+              }
+              return _label
+            },
+            labelLine: {
+              style: {
+                lineWidth: 0.5,
+              },
+            },
+            style: {
+              fill: color
+            }
+          })
+        }
+      }
+    
+    chart.interaction('element-highlight')
+    
+    chart.render()
   }
 
   /**
@@ -375,12 +701,18 @@
    */
   pierender = () => {
     const { plot, chartId } = this.state
-    let color = plot.color || 'rgba(0, 0, 0, 0.85)'
 
-    let X_axis = plot.Xaxis || 'x'
-    let Y_axis = plot.Yaxis || 'y'
+    if (plot.shape === 'nest') {
+      this.nestrender()
+      return
+    }
 
-    let data = this.getdata(X_axis, Y_axis)
+    let color = plot.color
+
+    let X_axis = plot.Xaxis
+    let Y_axis = plot.Yaxis
+
+    let data = this.getdata()
 
     const ds = new DataSet()
     const dv = ds.createView().source(data)

--
Gitblit v1.8.0