king
2020-09-16 c34bcb0a3054bdab29fbaff17e587c19d7b5de28
src/menu/components/chart/antv-bar/index.jsx
@@ -1,227 +1,588 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { InputItem, Icon, Checkbox, List, Button } from 'antd-mobile'
// import { createForm } from 'rc-form'
import { Chart } from '@antv/g2'
import DataSet from '@antv/data-set'
import zhCN from '@/locales/zh-CN/mob.js'
import enUS from '@/locales/en-US/mob.js'
import MKEmitter from '@/utils/events.js'
import asyncComponent from '@/utils/asyncComponent'
import Utils from '@/utils/utils.js'
import ContentUpdate from '@/mob/contupdate'
import mklogo from '@/assets/mobimg/mklogo.png'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
import './index.scss'
const CheckboxItem = Checkbox.CheckboxItem
const SettingComponent = asyncComponent(() => import('@/menu/datasource'))
const SearchComponent = asyncComponent(() => import('@/menu/searchcomponent'))
const ActionComponent = asyncComponent(() => import('@/menu/actioncomponent'))
const ChartCompileForm = asyncComponent(() => import('./chartcompile'))
class MobLogin extends Component {
class antvBarLineChart extends Component {
  static propTpyes = {
    menu: PropTypes.object,
    card: PropTypes.object,
    editId: PropTypes.any,
    triggerEdit: PropTypes.func,
    updateConfig: PropTypes.func,
    onDoubleClick: PropTypes.func
  }
  state = {
    dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    rember: true,
    param: {
      type: 'login',
      subtype: 'mob-login-1',
      box: { uuid: Utils.getuuid(), eleType: 'box', style: {color: '#ffffff', backgroundImage: 'linear-gradient(#378DBE, #46C29E, #48A9D6)'}},
      logo: { uuid: Utils.getuuid(), eleType: 'img', content: mklogo, style: {marginTop: '17vh', marginBottom: '15px'} },
      title: { uuid: Utils.getuuid(), eleType: 'text', content: '明科商业智能开放平台', style: {fontSize: '20px', fontWeight: 'bold', color: '#ffffff', textAlign: 'center', marginTop: '15px', marginBottom: '30px'}},
      login: { uuid: Utils.getuuid(), eleType: 'button', content: '登录', style: {fontSize: '18px', color: '#ffffff', textAlign: 'center', lineHeight: 2.4, borderRadius: '25px', marginBottom: '15vh'}},
      copyright: { uuid: Utils.getuuid(), eleType: 'textarea', content: 'Copyright©2017  所有相关版权归  北京明科普华信息技术有限公司', style: {fontSize: '12px', color: '#ffffff', textAlign: 'center'} }
    }
    card: null,
    eventListener: null
  }
  UNSAFE_componentWillMount () {
    const { card } = this.props
    const { card, menu } = this.props
    if (card.isNew) {
      // this.props.updateConfig({...param, ...card})
      let _plot = {
        chartType: card.type, // 图表类型
        enabled: 'false',     // 是否使用自定义设置
        datatype: 'query',    // 数据类型查询或统计
        customs: []
      }
      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,
        parentId: card.parentId || '',
        format: 'array',   // 组件属性 - 数据格式
        pageable: false,   // 组件属性 - 是否可分页
        switchable: false, // 组件属性 - 数据是否可切换
        dataName: dataName,
        subtype: card.subtype,
        setting: {span: card.floor === 1 ? 12 : 24, height: 400, interType: 'system', name: card.name},
        columns: [],
        scripts: [],
        search: [],
        action: [],
        plot: _plot
      }
      this.setState({
        card: _card
      })
      this.props.updateConfig(_card)
    } else {
      this.setState({
        card: fromJS(card).toJS()
      })
    }
  }
  componentDidMount () {
    this.viewrender()
    MKEmitter.addListener('tabsChange', this.handleTabsChange)
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
    return !is(fromJS(this.state), fromJS(nextState))
  }
  onChange = (e) => {
    const { rember } = this.state
    e.stopPropagation()
    this.setState({
      rember: !rember
    })
  }
  onChangeLang = (value) => {
    this.setState({
      lang: value
    })
  }
  editLogo = (e) => {
    const { card } = this.props
    e.stopPropagation()
    let element = {
      ...fromJS(card.logo.style).toJS(),
      componentId: card.uuid,
      uuid: card.logo.uuid,
      items: ['margin']
  /**
   * @description 组件销毁,清除state更新,清除快捷键设置
   */
  componentWillUnmount () {
    this.setState = () => {
      return
    }
    this.props.triggerEdit(element)
    MKEmitter.removeListener('tabsChange', this.handleTabsChange)
  }
  editTitle = (e) => {
    const { card } = this.props
    e.stopPropagation()
    let element = {
      ...fromJS(card.title.style).toJS(),
      componentId: card.uuid,
      uuid: card.title.uuid,
      items: ['font', 'margin'],
  handleTabsChange = (parentId) => {
    const { card } = this.state
    if (parentId === card.parentId) {
      let _element = document.getElementById(card.uuid)
      if (_element) {
        _element.innerHTML = ''
      }
      setTimeout(this.viewrender, 100)
    }
    this.props.triggerEdit(element)
  }
  editMsg = (e) => {
    const { card } = this.props
    e.stopPropagation()
    let element = {
      ...fromJS(card.copyright.style).toJS(),
      componentId: card.uuid,
      uuid: card.copyright.uuid,
      items: ['font'],
  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)
    }
    this.props.triggerEdit(element)
    return data
  }
  editLogin = (e) => {
    const { card } = this.props
    e.stopPropagation()
    let element = {
      ...fromJS(card.login.style).toJS(),
      componentId: card.uuid,
      uuid: card.login.uuid,
      items: ['font', 'background', 'border', 'margin']
  viewrender = () => {
    const { card } = this.state
    if (card.plot.chartType === 'line') {
      this.linerender()
    } else if (card.plot.chartType === 'bar') {
      this.barrender()
    }
    this.props.triggerEdit(element)
  }
  editBox = (e) => {
    const { card } = this.props
    e.stopPropagation()
    let element = {
      ...fromJS(card.box.style).toJS(),
      componentId: card.uuid,
      uuid: card.box.uuid,
      items: ['font', 'padding', 'background'],
    }
    this.props.triggerEdit(element)
  }
  linerender = () => {
    const { card } = this.state
    let plot = {...card.plot, height: card.setting.height - 70}
  updateContent = (card) => {
    Object.keys(card).forEach(key => {
      if (card[key] === null) {
        delete card[key]
    let transfield = {}
    card.columns.forEach(col => {
      if (col.field) {
        transfield[col.field] = col.label
      }
    })
    this.props.updateConfig(card)
    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)
      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]
            return row
          },
        })
      }
      const chart = new Chart({
        container: card.uuid,
        autoFit: true,
        height: plot.height || 400
      })
      chart.data(dv.rows)
      if (plot.coordinate !== 'polar') {
        chart.scale(X_axis, {
          range: [0, 1]
        })
      }
      chart.scale('value', {
        nice: true
      })
      if (!plot.legend || plot.legend === 'hidden') {
        chart.legend(false)
      } else {
        chart.legend({
          position: plot.legend
        })
      }
      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 _chart = chart
        .line()
        .position(`${X_axis}*value`)
        .color('key')
        .shape(plot.shape || 'smooth')
      if (plot.label === 'true') {
        _chart.label('value')
      }
      if (plot.point === 'true') {
        chart
          .point()
          .position(`${X_axis}*value`)
          .color('key')
          .size(3)
          .shape('circle')
      }
      chart.render()
    } else {
      this.customrender(data, transfield)
    }
  }
  render () {
    const { card, editId } = this.props
    // const { getFieldProps } = this.props.form
    const { rember } = this.state
  customrender = (data, transfield) => {
    const { plot } = this.props
    if (!card.box) return null
    let barfields = []
    let fields = []
    let legends = []
    let logoStyle = card.logo && card.logo.style ? fromJS(card.logo.style).toJS() : null
    if (logoStyle && logoStyle.marginTop && /vh$/ig.test(logoStyle.marginTop)) {
      let percent = parseInt(logoStyle.marginTop)
      logoStyle.marginTop = `calc(${(percent / 100) * 615}px)`
    }
    if (logoStyle && logoStyle.marginBottom && /vh$/ig.test(logoStyle.marginBottom)) {
      let percent = parseInt(logoStyle.marginBottom)
      logoStyle.marginBottom = `calc(${(percent / 100) * 625}px)`
    plot.customs.forEach(item => {
      item.name = transfield[item.field] || item.field
      if (item.axis === 'left') {
        item.index = 0
      } else if (item.axis === 'right') {
        item.index = 1
      } else {
        item.index = 2
      }
      if (item.chartType === 'bar') {
        barfields.push(item.field)
        fields.unshift(item)
      } else {
        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 } }
      })
    })
    fields.sort((a, b) => a.index - b.index)
    const ds = new DataSet()
    const dv = ds.createView().source(data)
    dv.transform({
      type: 'map',
      callback(row) {
        fields.forEach(line => {
          row[line.name] = row[line.field]
        })
        return row
      }
    })
    const chart = new Chart({
      container: plot.uuid,
      autoFit: true,
      height: plot.height || 400
    })
    chart.data(dv.rows)
    if (plot.coordinate !== 'polar' && barfields.length === 0) {
      chart.scale(plot.Xaxis, {
        range: [0, 1]
      })
    }
    let titleStyle = card.title && card.title.style ? fromJS(card.title.style).toJS() : null
    if (titleStyle && titleStyle.marginTop && /vh$/ig.test(titleStyle.marginTop)) {
      let percent = parseInt(titleStyle.marginTop)
      titleStyle.marginTop = `calc(${(percent / 100) * 615}px)`
    if (!plot.legend || plot.legend === 'hidden') {
      chart.legend(false)
    } else {
      chart.legend({
        custom: true,
        position: plot.legend,
        items: legends,
      })
    }
    if (titleStyle && titleStyle.marginBottom && /vh$/ig.test(titleStyle.marginBottom)) {
      let percent = parseInt(titleStyle.marginBottom)
      titleStyle.marginBottom = `calc(${(percent / 100) * 615}px)`
    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
      })
    }
    chart.scale({
      nice: true
    })
    fields.forEach((item, i) => {
      if (i === 0) {
        chart.axis(item.name, {
          grid: {},
          title: {},
          label: {}
        })
      } else if (i === 1 && item.axis !== 'unset') {
        chart.axis(item.name, {
          grid: null,
          title: {},
          label: {}
        })
      } else {
        chart.axis(item.name, {
          grid: null,
          title: null,
          label: null
        })
      }
      if (item.chartType === 'bar') {
        let _chart = chart
          .interval()
          .position(`${plot.Xaxis}*${item.name}`)
          .color(item.color)
          .shape(item.shape)
        if (item.label === 'true') {
          _chart.label(item.name)
        }
      } else if (item.chartType === 'line') {
        let _chart = chart
          .line()
          .position(`${plot.Xaxis}*${item.name}`)
          .color(item.color)
          .shape(item.shape)
        if (item.label === 'true') {
          _chart.label(item.name)
        }
        if (plot.point === 'true') {
          chart
            .point()
            .position(`${plot.Xaxis}*${item.name}`)
            .color(item.color)
            .size(3)
            .shape('circle')
        }
      }
    })
    chart.render()
  }
  barrender = () => {
    const { card } = this.state
    let plot = {...card.plot, height: card.setting.height - 70}
    let transfield = {}
    card.columns.forEach(col => {
      if (col.field) {
        transfield[col.field] = col.label
      }
    })
    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)
      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]
            return row
          },
        })
      }
      const chart = new Chart({
        container: card.uuid,
        autoFit: true,
        height: plot.height || 400
      })
      chart.data(dv.rows)
      chart.scale('value', {
        nice: true
      })
      if (!plot.legend || plot.legend === 'hidden') {
        chart.legend(false)
      } else {
        chart.legend({
          position: plot.legend
        })
      }
      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
        })
      }
      if (plot.adjust !== 'stack') {
        let _chart = chart
          .interval()
          .position(`${X_axis}*value`)
          .color('key')
          .adjust([
            {
              type: 'dodge',
              marginRatio: 0
            }
          ])
          .shape(plot.shape || 'rect')
        if (plot.label === 'true') {
          _chart.label('value')
        }
      } else if (plot.adjust === 'stack') {
        let _chart = chart
          .interval()
          .position(`${X_axis}*value`)
          .color('key')
          .adjust('stack')
          .shape(plot.shape || 'rect')
        if (plot.label === 'true') {
          _chart.label('value')
        }
      }
      chart.render()
    } else {
      this.customrender(data, transfield)
    }
  }
  updateComponent = (component) => {
    const card = fromJS(this.state.card).toJS()
    let refresh = false
    if (card.setting.span !== component.setting.span || card.setting.height !== component.setting.height || !is(fromJS(component.plot), fromJS(card.plot))) {
      let _element = document.getElementById(card.uuid)
      if (_element) {
        _element.innerHTML = ''
      }
      refresh = true
    }
    
    let loginStyle = fromJS(card.login.style).toJS()
    if (loginStyle.marginTop && /vh$/ig.test(loginStyle.marginTop)) {
      let percent = parseInt(loginStyle.marginTop)
      loginStyle.marginTop = `calc(${(percent / 100) * 615}px)`
    }
    if (loginStyle.marginBottom && /vh$/ig.test(loginStyle.marginBottom)) {
      let percent = parseInt(loginStyle.marginBottom)
      loginStyle.marginBottom = `calc(${(percent / 100) * 615}px)`
    }
    this.setState({
      card: component
    }, () => {
      if (refresh) {
        setTimeout(() => {
          this.viewrender()
        }, 100)
      }
    })
    this.props.updateConfig(component)
  }
  render() {
    const { card } = this.state
    const { menu } = this.props
    return (
      <div className="mob-login-1" onClick={this.editBox} style={card.box.style}>
        {card.logo ? <div className={'logo ' + (editId === card.logo.uuid ? 'editing' : '')} style={logoStyle} onClick={this.editLogo}>
          <ContentUpdate element={card.logo} updateContent={(ele) => this.updateContent({...card, logo: ele})}/>
          <img src={card.logo.content} alt=""/>
        </div> : null}
        {card.title ? <div className={'plat-name ' + (editId === card.title.uuid ? 'editing' : '')} style={titleStyle} onClick={this.editTitle}>
          <ContentUpdate element={card.title} updateContent={(ele) => this.updateContent({...card, title: ele})}/>
          {card.title.content}
        </div> : null}
        <InputItem
          placeholder={"UserName"}
          prefixListCls="mk-login-item am-list"
          disabled={true}
        >
          <Icon type="check-circle-o" />
        </InputItem>
        <InputItem
          placeholder="Password"
          prefixListCls="mk-login-item am-list"
          type={'password'}
          disabled={true}
        >
          <Icon type="check-circle" />
        </InputItem>
        <div className="other-setting">
          <CheckboxItem checked={rember} onChange={this.onChange}>
            <span onClick={this.onChange}>记住密码</span>
          </CheckboxItem>
          {/* <Picker data={langs} value={lang} cols={1} onChange={this.onChangeLang} className="forss">
            <List.Item>{lang}</List.Item>
          </Picker> */}
          <List.Item className="lang">中文简体</List.Item>
          <div className="clear-both"></div>
      <div className="menu-line-chart-edit-box" style={{height: card.setting.height || 400}}>
        <SettingComponent
          config={card}
          menu={menu}
          updateConfig={this.updateComponent}
        />
        <div className="chart-header">
          <span className="chart-title">{card.setting.title || ''}</span>
          <SearchComponent
            menu={menu}
            config={card}
            sysRoles={menu.sysRoles}
            optionLibs={null}
            updatesearch={this.updateComponent}
          />
        </div>
        <Button
          type="primary"
          className={'login ' + (editId === card.login.uuid ? 'editing' : '')}
          onDoubleClick={() => this.props.doubleClickCard(card.login)}
          style={loginStyle}
          onClick={this.editLogin}
        >
          <ContentUpdate element={card.login} deletable={false} updateContent={(ele) => this.updateContent({...card, login: ele})}/>
          {card.login.content}
        </Button>
        {card.copyright ? <div className={'company-msg ' + (editId === card.copyright.uuid ? 'editing' : '')} style={card.copyright.style} onClick={this.editMsg}>
          <ContentUpdate element={card.copyright} updateContent={(ele) => this.updateContent({...card, copyright: ele})}/>
          {card.copyright.content}
        </div> : null}
        <ActionComponent
          type="chart"
          menu={menu}
          config={card}
          tabs={[]}
          // setSubConfig={(_btn) => this.setSubConfig(_btn, 'button')}
          updateaction={this.updateComponent}
        />
        <div className="canvas" id={card.uuid}></div>
        <ChartCompileForm
          config={card}
          dict={this.state.dict}
          plotchange={this.updateComponent}
        />
      </div>
    )
  }
}
// export default createForm()(MobLogin)
export default MobLogin
export default antvBarLineChart