king
2020-10-23 407c0f1765c7d085218a91ad8842784977383d05
src/menu/components/chart/antv-bar/index.jsx
@@ -1,50 +1,99 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import {connect} from 'react-redux'
import { is, fromJS } from 'immutable'
import { Icon, Popover } from 'antd'
import { Chart } from '@antv/g2'
import DataSet from '@antv/data-set'
import MKEmitter from '@/utils/events.js'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import zhCN from '@/locales/zh-CN/mob.js'
import enUS from '@/locales/en-US/mob.js'
// import ChartCompileForm from './chartcompile'
import Utils from '@/utils/utils.js'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
import './index.scss'
const SettingComponent = asyncComponent(() => import('@/menu/datasourcecomponent'))
const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
const SearchComponent = asyncComponent(() => import('@/menu/searchcomponent'))
const ActionComponent = asyncComponent(() => import('@/menu/actioncomponent'))
const ChartCompileForm = asyncIconComponent(() => import('./chartcompile'))
class antvBarLineChart extends Component {
  static propTpyes = {
    config: PropTypes.object,
    card: PropTypes.object,
    editId: PropTypes.any,
    triggerEdit: PropTypes.func,
    updateConfig: PropTypes.func,
    deletecomponent: PropTypes.func,
  }
  state = {
    dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    card: null,
    visible: true
    eventListener: null
  }
  UNSAFE_componentWillMount () {
    const { card, config } = this.props
    const { card, menu } = this.props
    console.log(config)
    if (card.isNew) {
      let _plot = {
        chartType: card.type, // 图表类型
        enabled: 'false',     // 是否使用自定义设置
        datatype: 'query',    // 数据类型查询或统计
        customs: [],
        width: 24,
        height: 400,
        name: card.name
      }
      if (card.subtype === 'bar') {
        _plot.coordinate = 'angle' // 二维坐标或极坐标
        _plot.transpose = 'false'  // 坐标轴变换
      } else if (card.subtype === 'bar1') {
        _plot.coordinate = 'angle'
        _plot.transpose = 'true'
      } else if (card.subtype === 'line') {
        _plot.shape = 'smooth'
      } else if (card.subtype === 'line1') {
        _plot.shape = 'hv'
      }
      let dataName = ''
      if (card.floor === 1) {
        while (!dataName) {
          let _dataName = Utils.getdataName()
          if (menu.components.filter(com => com.dataName === _dataName).length === 0) {
            dataName = _dataName
          }
        }
      }
      let _card = {
        uuid: card.uuid,
        type: card.type,
        floor: card.floor,
        tabId: card.tabId || '',
        parentId: card.parentId || '',
        format: 'array',   // 组件属性 - 数据格式
        pageable: false,   // 组件属性 - 是否可分页
        switchable: false, // 组件属性 - 数据是否可切换
        dataName: dataName,
        width: _plot.width,
        name: _plot.name,
        subtype: card.subtype,
        setting: {span: 12, height: 400},
        setting: { interType: 'system' },
        style: {
          fontSize: '16px',
          borderWidth: '1px', borderColor: 'rgb(217, 217, 217)',
          marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px'
        },
        columns: [],
        scripts: [],
        search: [],
        action: [],
        plot: {type: card.type, Xaxis: '', Yaxis: null}
        plot: _plot
      }
      this.setState({
        card: _card
@@ -59,13 +108,35 @@
  componentDidMount () {
    this.viewrender()
    MKEmitter.addListener('tabsChange', this.handleTabsChange)
    MKEmitter.addListener('submitStyle', this.getStyle)
  }
  UNSAFE_componentWillReceiveProps (nextProps) {
    if (!is(fromJS(this.props.plot), fromJS(nextProps.plot))) {
      this.setState({}, () => {
        this.viewrender()
      })
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
  }
  /**
   * @description 组件销毁,清除state更新,清除快捷键设置
   */
  componentWillUnmount () {
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('tabsChange', this.handleTabsChange)
    MKEmitter.removeListener('submitStyle', this.getStyle)
  }
  handleTabsChange = (parentId) => {
    const { card } = this.state
    if (parentId === card.parentId) {
      let _element = document.getElementById(card.uuid)
      if (_element) {
        _element.innerHTML = ''
      }
      setTimeout(this.viewrender, 100)
    }
  }
@@ -96,18 +167,20 @@
  viewrender = () => {
    const { card } = this.state
    if (card.plot.type === 'line') {
    if (card.plot.chartType === 'line') {
      this.linerender()
    } else if (card.plot.type === 'bar') {
    } else if (card.plot.chartType === 'bar') {
      this.barrender()
    }
  }
  linerender = () => {
    const { plot, config } = this.props
    const { card } = this.state
    let plot = {...card.plot, height: card.plot.height - 80} // 去除title所占空间
    let color = plot.color || 'rgba(0, 0, 0, 0.85)'
    let transfield = {}
    config.columns.forEach(col => {
    card.columns.forEach(col => {
      if (col.field) {
        transfield[col.field] = col.label
      }
@@ -140,12 +213,37 @@
      }
      const chart = new Chart({
        container: plot.uuid,
        container: card.uuid,
        autoFit: true,
        height: plot.height || 400
      })
  
      chart.data(dv.rows)
      chart.axis(X_axis, {
        label: {
          style: {
            fill: color,
          }
        },
        line: {
          style: {
            fill: color,
          }
        }
      })
      chart.axis('value', {
        grid: {
          style: {
            fill: color,
          }
        },
        label: {
          style: {
            fill: color,
          }
        }
      })
  
      if (plot.coordinate !== 'polar') {
        chart.scale(X_axis, {
@@ -160,7 +258,12 @@
        chart.legend(false)
      } else {
        chart.legend({
          position: plot.legend
          position: plot.legend,
          itemName: {
            style: {
              fill: color,
            }
          }
        })
      }
  
@@ -208,7 +311,9 @@
  }
  customrender = (data, transfield) => {
    const { plot } = this.props
    const { card } = this.state
    let plot = {...card.plot, height: card.plot.height - 80} // 去除title所占空间
    let color = plot.color || 'rgba(0, 0, 0, 0.85)'
    let barfields = []
    let fields = []
@@ -260,6 +365,31 @@
    chart.data(dv.rows)
    chart.axis(plot.Xaxis, {
      label: {
        style: {
          fill: color,
        }
      },
      line: {
        style: {
          fill: color,
        }
      }
    })
    chart.axis('value', {
      grid: {
        style: {
          fill: color,
        }
      },
      label: {
        style: {
          fill: color,
        }
      }
    })
    if (plot.coordinate !== 'polar' && barfields.length === 0) {
      chart.scale(plot.Xaxis, {
        range: [0, 1]
@@ -273,6 +403,11 @@
        custom: true,
        position: plot.legend,
        items: legends,
        itemName: {
          style: {
            fill: color,
          }
        }
      })
    }
@@ -280,7 +415,7 @@
      chart.tooltip(false)
    } else {
      chart.tooltip({
        shared: true
        shared: true,
      })
    }
@@ -357,8 +492,8 @@
  barrender = () => {
    const { card } = this.state
    let plot = {...card.plot, height: card.setting.height - 70}
    let plot = {...card.plot, height: card.plot.height - 80}
    let color = plot.color || 'rgba(0, 0, 0, 0.85)'
    let transfield = {}
    card.columns.forEach(col => {
@@ -370,8 +505,6 @@
    let Y_axis = plot.Yaxis || ['y']
    let data = this.getdata(X_axis, Y_axis)
    console.log(plot)
    console.log(data)
    
    if (plot.enabled !== 'true') {
      const ds = new DataSet()
@@ -400,8 +533,32 @@
        height: plot.height || 400
      })
  
      console.log(dv.rows)
      chart.data(dv.rows)
      chart.axis(X_axis, {
        label: {
          style: {
            fill: color,
          }
        },
        line: {
          style: {
            fill: color,
          }
        }
      })
      chart.axis('value', {
        grid: {
          style: {
            fill: color,
          }
        },
        label: {
          style: {
            fill: color,
          }
        }
      })
  
      chart.scale('value', {
        nice: true
@@ -411,7 +568,12 @@
        chart.legend(false)
      } else {
        chart.legend({
          position: plot.legend
          position: plot.legend,
          itemName: {
            style: {
              fill: color,
            }
          }
        })
      }
  
@@ -469,84 +631,147 @@
    }
  }
  plotChange = (_plot) => {
    const { config } = this.props
    if (_plot.datatype === 'statistics') {
      _plot.Yaxis = [_plot.InfoValue]
    }
    let _charts = fromJS(config.charts).toJS()
    _charts = _charts.map(item => {
      if (item.uuid === _plot.uuid) {
        if (!is(fromJS(item), fromJS(_plot))) {
          let _element = document.getElementById(_plot.uuid)
          if (_element) {
            _element.innerHTML = ''
          }
        }
        return _plot
      }
      return item
    })
    this.props.plotchange({...config, charts: _charts})
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
  }
  updateComponent = (component) => {
    const card = fromJS(this.state.card).toJS()
    let refresh = false
    if (!is(fromJS(component.plot), fromJS(card.plot))) {
      let _element = document.getElementById(card.uuid)
      if (_element) {
        _element.innerHTML = ''
      }
      refresh = true
    }
    component.width = component.plot.width
    component.name = component.plot.name
    this.setState({
      card: component
    }, () => {
      if (refresh) {
        setTimeout(() => {
          this.viewrender()
        }, 100)
      }
    })
    this.props.updateConfig(component)
  }
  addSearch = () => {
    const { card } = this.state
    let newcard = {}
    newcard.uuid = Utils.getuuid()
    newcard.focus = true
    newcard.label = 'label'
    newcard.initval = ''
    newcard.type = 'select'
    newcard.resourceType = '0'
    newcard.options = []
    newcard.setAll = 'false'
    newcard.orderType = 'asc'
    newcard.display = 'dropdown'
    newcard.match = '='
    // 注册事件-添加搜索
    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.method = 'POST'
    newcard.execSuccess = 'grid'
    newcard.execError = 'never'
    newcard.popClose = 'never'
    newcard.errorTime = 10
    newcard.verify = null
    newcard.show = 'icon'
    // 注册事件-添加按钮
    MKEmitter.emit('addButton', card.uuid, newcard)
  }
  changeStyle = () => {
    const { card } = this.state
    MKEmitter.emit('changeStyle', [card.uuid], ['font', 'background', 'border', 'padding', 'margin'], card.style)
  }
  getStyle = (comIds, style) => {
    const { card } = this.state
    if (comIds.length !== 1 || comIds[0] !== card.uuid) return
    let _card = {...card, style}
    this.setState({
      card: _card
    })
    this.props.updateConfig(_card)
  }
  render() {
    const { card } = this.state
    const { config } = this.props
    return (
      <div className="line-chart-edit-box" style={{height: card.setting.height || 400}}>
        <SettingComponent
          config={{...card, tables: config.tables}}
          MenuID={config.uuid}
          tableFields={config.tableFields || []}
          permFuncField={config.permFuncField || []}
          updateConfig={this.updateComponent}
        />
      <div className="menu-line-chart-edit-box" style={{...card.style, height: card.plot.height || 400}}>
        <div className="chart-header">
          <span className="chart-title">{card.setting.title || ''}</span>
          <span className="chart-title">{card.plot.title || ''}</span>
          <SearchComponent
            menu={{MenuID: config.uuid, MenuName: config.MenuName}}
            config={card}
            sysRoles={config.sysRoles}
            optionLibs={null}
            updatesearch={this.updateComponent}
          />
          <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
            <div className="mk-popover-control">
              <Icon className="plus" title="添加搜索" onClick={this.addSearch} type="plus-circle" />
              <Icon className="plus" title="添加按钮" onClick={this.addButton} type="plus-square" />
              <ChartCompileForm config={card} dict={this.state.dict} plotchange={this.updateComponent}/>
              <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" />
              <Icon className="close" title="delete" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
              <SettingComponent config={card} updateConfig={this.updateComponent}/>
            </div>
          } trigger="hover">
            <Icon type="tool" />
          </Popover>
        </div>
        <ActionComponent
          menu={{ MenuID: config.uuid, MenuName: config.MenuName, MenuNo: config.MenuNo, fstMenuList: config.fstMenuList }}
          type="chart"
          plus="false"
          config={card}
          tabs={[]}
          usefulFields={config.permFuncField || []}
          // setSubConfig={(_btn) => this.setSubConfig(_btn, 'button')}
          updateaction={this.updateComponent}
        />
        <div className="canvas" id={card.uuid}></div>
        {/* <ChartCompileForm
          plot={plot}
          type={plot.chartType}
          config={this.props.config}
          dict={this.state.dict}
          plotchange={this.plotChange}
        /> */}
      </div>
    )
  }
}
export default antvBarLineChart
const mapStateToProps = (state) => {
  return {
    menu: state.customMenu
  }
}
const mapDispatchToProps = () => {
  return {}
}
export default connect(mapStateToProps, mapDispatchToProps)(antvBarLineChart)