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