| | |
| | | import { is, fromJS } from 'immutable' |
| | | import { Chart } from '@antv/g2' |
| | | import DataSet, { DataView } from '@antv/data-set' |
| | | import { Spin, Empty, notification, Modal } from 'antd' |
| | | import { DownloadOutlined } from '@ant-design/icons' |
| | | import { Spin, Empty } from 'antd' |
| | | // import { DownloadOutlined } from '@ant-design/icons' |
| | | import moment from 'moment' |
| | | |
| | | import Api from '@/api' |
| | |
| | | this.data = window.GLOB.SyncData.get(_config.dataName) || [] |
| | | |
| | | if (_config.$cache) { |
| | | Api.writeCacheConfig(_config.uuid, fromJS(this.data).toJS()) |
| | | Api.writeCacheConfig(_config.uuid, fromJS(this.data).toJS(), BID) |
| | | } |
| | | |
| | | _config.setting.sync = 'false' |
| | |
| | | } |
| | | |
| | | initExec = () => { |
| | | const { config } = this.state |
| | | const { config, BID } = this.state |
| | | |
| | | if (config.$cache) { |
| | | if (config.$time) { |
| | | if (!this.loaded) { |
| | | Api.getLCacheConfig(config.uuid, config.$time).then(res => { |
| | | Api.getLCacheConfig(config.uuid, config.$time, BID).then(res => { |
| | | if (!res.valid && config.setting.onload === 'true') { |
| | | setTimeout(() => { |
| | | this.loadData('init') |
| | |
| | | } |
| | | } else { |
| | | if (!this.loaded) { |
| | | Api.getLCacheConfig(config.uuid, 0).then(res => { |
| | | Api.getLCacheConfig(config.uuid, 0, BID).then(res => { |
| | | if (!res.data || this.loaded) return |
| | | |
| | | this.data = res.data |
| | |
| | | } |
| | | |
| | | transferSyncData = (syncId) => { |
| | | const { config } = this.state |
| | | const { config, BID } = this.state |
| | | |
| | | if (config.$syncId !== syncId) return |
| | | |
| | | let _data = window.GLOB.SyncData.get(config.dataName) || [] |
| | | |
| | | if (config.$cache) { |
| | | Api.writeCacheConfig(config.uuid, fromJS(_data).toJS()) |
| | | Api.writeCacheConfig(config.uuid, fromJS(_data).toJS(), BID) |
| | | } |
| | | |
| | | this.data = _data |
| | |
| | | let result = await Api.genericInterface(param) |
| | | if (result.status) { |
| | | if (config.$cache && type === 'init') { |
| | | Api.writeCacheConfig(config.uuid, result.data || []) |
| | | Api.writeCacheConfig(config.uuid, result.data || [], BID) |
| | | } |
| | | this.loaded = true |
| | | |
| | |
| | | this.timer && this.timer.stop() |
| | | } |
| | | } |
| | | if (result.message) { |
| | | if (result.ErrCode === 'Y') { |
| | | Modal.success({ |
| | | title: result.message |
| | | }) |
| | | } else if (result.ErrCode === 'S') { |
| | | notification.success({ |
| | | top: 92, |
| | | message: result.message, |
| | | duration: 2 |
| | | }) |
| | | } |
| | | } |
| | | |
| | | UtilsDM.querySuccess(result) |
| | | } else { |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | this.timer && this.timer.stop() |
| | | |
| | | if (!result.message) return |
| | | if (result.ErrCode === 'N') { |
| | | Modal.error({ |
| | | title: result.message, |
| | | }) |
| | | } else if (result.ErrCode !== '-2') { |
| | | notification.error({ |
| | | top: 92, |
| | | message: result.message, |
| | | duration: 10 |
| | | }) |
| | | } |
| | | UtilsDM.queryFail(result) |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description 图表数据预处理 |
| | | * 1、通过显示列进行数据类型转换 |
| | | * 2、重复数据:取平均值、累计、去重 |
| | | * 3、柱状图数据补齐 |
| | | */ |
| | | getdata = () => { |
| | | const { plot } = this.state |
| | |
| | | if (this.data.length === 0) { |
| | | this.setState({empty: true}) |
| | | return [] |
| | | } else { |
| | | this.setState({empty: false}) |
| | | } |
| | | |
| | | let _data = [] |
| | | let _cdata = fromJS(this.data).toJS() |
| | | |
| | | if (plot.repeat === 'average') { |
| | | let _mdata = new Map() |
| | | _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]) { |
| | | return |
| | | return fromJS(this.data).toJS().map(item => { |
| | | if (typeof(item[plot.Yaxis]) !== 'number') { |
| | | item[plot.Yaxis] = parseFloat(item[plot.Yaxis]) |
| | | if (isNaN(item[plot.Yaxis])) { |
| | | item[plot.Yaxis] = 0 |
| | | } |
| | | } |
| | | |
| | | if (!_mdata.has(item[plot.Xaxis])) { |
| | | item.$count = 1 |
| | | _mdata.set(item[plot.Xaxis], item) |
| | | } else { |
| | | let _item = _mdata.get(item[plot.Xaxis]) |
| | | _item.$count++ |
| | | _item[plot.Yaxis] += item[plot.Yaxis] |
| | | _mdata.set(item[plot.Xaxis], _item) |
| | | } |
| | | }) |
| | | item[plot.Yaxis] = +item[plot.Yaxis].toFixed(plot.$decimal) |
| | | |
| | | _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() |
| | | _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]) { |
| | | return |
| | | } |
| | | |
| | | if (!_mdata.has(item[plot.Xaxis])) { |
| | | _mdata.set(item[plot.Xaxis], item) |
| | | } else { |
| | | let _item = _mdata.get(item[plot.Xaxis]) |
| | | _item[plot.Yaxis] += item[plot.Yaxis] |
| | | _mdata.set(item[plot.Xaxis], _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() |
| | | _cdata.forEach(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 |
| | | return item |
| | | }) |
| | | } |
| | | |
| | | getnestdata = () => { |
| | |
| | | } |
| | | |
| | | let _data = [] |
| | | let _cdata = fromJS(this.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]) { |
| | | let _mdata = new Map() |
| | | let map = new Map() |
| | | let sort = 1 |
| | | fromJS(this.data).toJS().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 |
| | | } |
| | | } |
| | | |
| | | item.$type = item[plot.type] |
| | | let sign = item.$type + item[plot.Xaxis] |
| | | item.$type = item[plot.type] |
| | | |
| | | if (!_mdata.has(sign)) { |
| | | let _sort = sort |
| | | if (map.has(item.$type)) { |
| | | _sort = map.get(item.$type) |
| | | } else { |
| | | map.set(item.$type, _sort) |
| | | sort++ |
| | | } |
| | | 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) |
| | | } |
| | | }) |
| | | item.$sort = _sort |
| | | item[plot.Yaxis] = +item[plot.Yaxis].toFixed(plot.$decimal) |
| | | |
| | | _data = [..._mdata.values()] |
| | | _data = _data.map(item => { |
| | | item[plot.Yaxis] = item[plot.Yaxis] / item.$count |
| | | item[plot.Yaxis] = +item[plot.Yaxis].toFixed(plot.$decimal) |
| | | _mdata.set(sign, true) |
| | | |
| | | 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 |
| | | } |
| | | |
| | | item.$type = item[plot.type] |
| | | let sign = item.$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 |
| | | } |
| | | } |
| | | |
| | | item.$type = item[plot.type] |
| | | |
| | | 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()] |
| | | } |
| | | _data.push(item) |
| | | }) |
| | | |
| | | this.setState({empty: _data.length === 0}) |
| | | |
| | |
| | | height: plot.height |
| | | }) |
| | | |
| | | if (plot.shape !== 'nightingale' && plot.show !== 'value') { |
| | | if (plot.show !== 'value') { |
| | | dv.transform({ |
| | | type: 'percent', |
| | | field: Y_axis, |
| | |
| | | |
| | | chart.data(dv.rows) |
| | | |
| | | if (plot.shape === 'nightingale') { |
| | | chart.coordinate('polar', { |
| | | innerRadius: plot.innerRadius ? (plot.innerRadius / 100) : 0, |
| | | radius: plot.radius ? (plot.radius / 100) : 0.75, |
| | | }) |
| | | } else { |
| | | chart.coordinate('theta', { |
| | | innerRadius: plot.shape !== 'pie' && plot.innerRadius ? (plot.innerRadius / 100) : 0, |
| | | radius: plot.radius ? (plot.radius / 100) : 0.75, |
| | | }) |
| | | } |
| | | chart.coordinate('theta', { |
| | | innerRadius: plot.shape !== 'pie' && plot.innerRadius ? (plot.innerRadius / 100) : 0, |
| | | radius: plot.radius ? (plot.radius / 100) : 0.75, |
| | | }) |
| | | |
| | | if (!plot.legend || plot.legend === 'hidden') { |
| | | chart.legend(false) |
| | | } else if (plot.shape === 'nightingale') { |
| | | chart.legend(X_axis, { |
| | | position: plot.legend, |
| | | itemName: { |
| | | style: { fill: color } |
| | | } |
| | | }) |
| | | } else { |
| | | chart.legend({ |
| | | position: plot.legend, |
| | |
| | | }) |
| | | } |
| | | |
| | | if (plot.shape !== 'nightingale') { |
| | | let _chart = chart |
| | | .interval() |
| | | .adjust('stack') |
| | | .position(Y_axis) |
| | | .tooltip(`${X_axis}*${Y_axis}`, (name, value) => { |
| | | if (plot.show !== 'value') { |
| | | value = (value * 100).toFixed(2) + '%' |
| | | } |
| | | return { |
| | | name: name, |
| | | value: value |
| | | } |
| | | }) |
| | | |
| | | if (plot.splitLine) { |
| | | _chart.style({ |
| | | lineWidth: plot.splitLine, |
| | | stroke: plot.splitColor, |
| | | }) |
| | | } |
| | | if (plot.colors && plot.colors.length > 0) { |
| | | let limit = chartColors.length |
| | | _chart.color(X_axis, (type) => { |
| | | if (colors.has(type)) { |
| | | return colors.get(type) |
| | | } else { |
| | | let _c = chartColors[colorIndex % limit] |
| | | colors.set(type, _c) |
| | | colorIndex++ |
| | | return _c |
| | | } |
| | | }) |
| | | } else { |
| | | _chart.color(X_axis) |
| | | } |
| | | if (plot.label !== 'false') { |
| | | if (plot.label === 'inner') { |
| | | _chart.label(Y_axis, { |
| | | offset: -30, |
| | | content: (data) => { |
| | | let _val = '' |
| | | if (plot.show !== 'value') { |
| | | _val = `${(data[Y_axis] * 100).toFixed(2)}%` |
| | | } else { |
| | | _val = `${data[Y_axis]}` |
| | | } |
| | | return _val |
| | | }, |
| | | style: { |
| | | textAlign: 'center', |
| | | fontSize: 16, |
| | | shadowBlur: 2, |
| | | shadowColor: 'rgba(0, 0, 0, .45)', |
| | | fill: '#fff', |
| | | } |
| | | }) |
| | | } else { |
| | | _chart.label(Y_axis, { |
| | | layout: { type: plot.label === 'outer' ? 'pie-spider' : 'fixed-overlap' }, |
| | | labelHeight: 20, |
| | | content: (data) => { |
| | | let _val = '' |
| | | if (plot.show !== 'value') { |
| | | _val = `${(data[Y_axis] * 100).toFixed(2)}%` |
| | | } else { |
| | | _val = `${data[Y_axis]}` |
| | | } |
| | | |
| | | return `${data[X_axis]}: ${_val}` |
| | | }, |
| | | labelLine: { |
| | | style: { |
| | | lineWidth: 0.5, |
| | | }, |
| | | }, |
| | | style: { |
| | | fill: color |
| | | } |
| | | }) |
| | | let _chart = chart |
| | | .interval() |
| | | .adjust('stack') |
| | | .position(Y_axis) |
| | | .tooltip(`${X_axis}*${Y_axis}`, (name, value) => { |
| | | if (plot.show !== 'value') { |
| | | value = (value * 100).toFixed(2) + '%' |
| | | } |
| | | } |
| | | } else { |
| | | chart.axis(false) |
| | | let _chart = chart |
| | | .interval() |
| | | .position(`${X_axis}*${Y_axis}`) |
| | | return { |
| | | name: name, |
| | | value: value |
| | | } |
| | | }) |
| | | |
| | | if (plot.colors && plot.colors.length > 0) { |
| | | let limit = chartColors.length |
| | | _chart.color(X_axis, (type) => { |
| | | if (colors.has(type)) { |
| | | return colors.get(type) |
| | | } else { |
| | | let _c = chartColors[colorIndex % limit] |
| | | colors.set(type, _c) |
| | | colorIndex++ |
| | | return _c |
| | | if (plot.splitLine) { |
| | | _chart.style({ |
| | | lineWidth: plot.splitLine, |
| | | stroke: plot.splitColor, |
| | | }) |
| | | } |
| | | if (plot.colors && plot.colors.length > 0) { |
| | | let limit = chartColors.length |
| | | _chart.color(X_axis, (type) => { |
| | | if (colors.has(type)) { |
| | | return colors.get(type) |
| | | } else { |
| | | let _c = chartColors[colorIndex % limit] |
| | | colors.set(type, _c) |
| | | colorIndex++ |
| | | return _c |
| | | } |
| | | }) |
| | | } else { |
| | | _chart.color(X_axis) |
| | | } |
| | | if (plot.label !== 'false') { |
| | | if (plot.label === 'inner') { |
| | | _chart.label(Y_axis, { |
| | | offset: -30, |
| | | content: (data) => { |
| | | let _val = '' |
| | | if (plot.show !== 'value') { |
| | | _val = `${(data[Y_axis] * 100).toFixed(2)}%` |
| | | } else { |
| | | _val = `${data[Y_axis]}` |
| | | } |
| | | return _val |
| | | }, |
| | | style: { |
| | | textAlign: 'center', |
| | | fontSize: 16, |
| | | shadowBlur: 2, |
| | | shadowColor: 'rgba(0, 0, 0, .45)', |
| | | fill: '#fff', |
| | | } |
| | | }) |
| | | } else { |
| | | _chart.color(X_axis) |
| | | } |
| | | if (plot.label !== 'false') { |
| | | let _label = {} |
| | | if (plot.label === 'inner') { |
| | | _label.offset = -15 |
| | | } else { |
| | | _label.style = { |
| | | _chart.label(Y_axis, { |
| | | layout: { type: plot.label === 'outer' ? 'pie-spider' : 'fixed-overlap' }, |
| | | labelHeight: 20, |
| | | content: (data) => { |
| | | let _val = '' |
| | | if (plot.show !== 'value') { |
| | | _val = `${(data[Y_axis] * 100).toFixed(2)}%` |
| | | } else { |
| | | _val = `${data[Y_axis]}` |
| | | } |
| | | |
| | | return `${data[X_axis]}: ${_val}` |
| | | }, |
| | | labelLine: { |
| | | style: { |
| | | lineWidth: 0.5, |
| | | }, |
| | | }, |
| | | style: { |
| | | fill: color |
| | | } |
| | | } |
| | | |
| | | _chart.label(X_axis, _label) |
| | | } |
| | | if (plot.splitLine) { |
| | | _chart.style({ |
| | | lineWidth: plot.splitLine, |
| | | stroke: plot.splitColor, |
| | | }) |
| | | } |
| | | } |
| | |
| | | let menu_id = plot.linkmenu.slice(-1)[0] |
| | | |
| | | chart.on('element:dblclick', (ev) => { |
| | | let menu = window.GLOB.mkThdMenus.filter(m => m.MenuID === menu_id)[0] || '' |
| | | let menu = window.GLOB.mkThdMenus.get(menu_id) || '' |
| | | |
| | | if (!menu) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '菜单已删除或没有访问权限!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | if (!menu) return |
| | | |
| | | try { |
| | | let data = ev.data.data |
| | |
| | | } |
| | | <NormalHeader config={config} BID={BID} refresh={this.refreshSearch} /> |
| | | <div className="canvas-wrap"> |
| | | {config.plot.download === 'enable' && this.state.chart && !empty ? <DownloadOutlined onClick={this.downloadImage} className="system-color download"/> : null} |
| | | {/* {config.plot.download === 'enable' && this.state.chart && !empty ? <DownloadOutlined onClick={this.downloadImage} className="system-color download"/> : null} */} |
| | | <div className={'canvas' + (empty ? ' empty' : '')} id={this.state.chartId}></div> |
| | | </div> |
| | | {empty ? <Empty description={false}/> : null} |