| | |
| | | } |
| | | }, |
| | | "@antv/component": { |
| | | "version": "0.7.9", |
| | | "resolved": "https://registry.npmjs.org/@antv/component/-/component-0.7.9.tgz", |
| | | "integrity": "sha512-K0nephuK9+6wrR9SCcfDHLCN+C5caKaWC3V739G0ZcYAJ23616Eq5iwl2JsGnjZOebxmYqDxhwTu7csftebkKg==", |
| | | "version": "0.8.2", |
| | | "resolved": "https://registry.npmjs.org/@antv/component/-/component-0.8.2.tgz", |
| | | "integrity": "sha512-aU65T9jD85H+3WhhmgPz8kiuqxJGPuHFgRiBYmR+vQUnAA2nOW2bCafiNx/bSEAqmVgsr+8e+9IDQZ6PowIgtQ==", |
| | | "requires": { |
| | | "@antv/dom-util": "~2.0.1", |
| | | "@antv/g-base": "~0.5.0", |
| | |
| | | } |
| | | }, |
| | | "@antv/g-canvas": { |
| | | "version": "0.5.1", |
| | | "resolved": "https://registry.npmjs.org/@antv/g-canvas/-/g-canvas-0.5.1.tgz", |
| | | "integrity": "sha512-m132AyMrILm0wYTbXSlmDaz8M7OoEIvSZuW59apDS+F3jHAxsJrBvKXJjJJ26CItdIbTmeLLMcfoGIj9IzXvDw==", |
| | | "version": "0.5.3", |
| | | "resolved": "https://registry.npmjs.org/@antv/g-canvas/-/g-canvas-0.5.3.tgz", |
| | | "integrity": "sha512-80k1BbiY05heHKUm4o6IL6KVRZS+uAgzdIF2OaC9grQc6KxrJoK2dCxKpmna3NBHTU9Sm+/rsiGcL7lp7S+ecQ==", |
| | | "requires": { |
| | | "@antv/g-base": "^0.5.1", |
| | | "@antv/g-math": "^0.1.5", |
| | |
| | | } |
| | | }, |
| | | "@antv/g-svg": { |
| | | "version": "0.5.1", |
| | | "resolved": "https://registry.npmjs.org/@antv/g-svg/-/g-svg-0.5.1.tgz", |
| | | "integrity": "sha512-UALLDneKlpOaAZXMIRsUjDrmuceXGR0shXwj4gv+UzIgYe/4hNxTll+1RsA+R+tYmQKAhsilhzsm3eMmPzwbtA==", |
| | | "version": "0.5.2", |
| | | "resolved": "https://registry.npmjs.org/@antv/g-svg/-/g-svg-0.5.2.tgz", |
| | | "integrity": "sha512-T0PYjIM+WX6zv3yUgSkyRcHFq4hlio0MeRGoJR60P5U5MNSdkZnblcu79cpU2i42Z7wBr404Kv1dplCGxC38PA==", |
| | | "requires": { |
| | | "@antv/g-base": "^0.5.1", |
| | | "@antv/g-math": "^0.1.5", |
| | |
| | | } |
| | | }, |
| | | "@antv/g2": { |
| | | "version": "4.1.0-beta.13", |
| | | "resolved": "https://registry.npmjs.org/@antv/g2/-/g2-4.1.0-beta.13.tgz", |
| | | "integrity": "sha512-wmDUbeTbRKg/GZ5cP9HfaszraPgbi9lzYBbGPDjddajYKxCG25jbbGYVBMjByAkXuq7pGCXa8xixh+G4cmPcPg==", |
| | | "version": "4.1.0-beta.18", |
| | | "resolved": "https://registry.npmjs.org/@antv/g2/-/g2-4.1.0-beta.18.tgz", |
| | | "integrity": "sha512-RW3e95V2aUtys36guS7PNHbfgyYZgigu18OLSYPkgyRLF0pPABcSrIot+xnVGQ4Cx0ZDmhJVTvpXjU4QMa96kw==", |
| | | "requires": { |
| | | "@antv/adjust": "^0.2.1", |
| | | "@antv/attr": "^0.3.1", |
| | | "@antv/color-util": "^2.0.2", |
| | | "@antv/component": "^0.7.0", |
| | | "@antv/component": "^0.8.0", |
| | | "@antv/coord": "^0.3.0", |
| | | "@antv/dom-util": "^2.0.2", |
| | | "@antv/event-emitter": "~0.1.0", |
| | |
| | | "private": true, |
| | | "dependencies": { |
| | | "@antv/data-set": "^0.11.4", |
| | | "@antv/g2": "^4.1.0-beta.13", |
| | | "@antv/g2": "^4.1.0-beta.18", |
| | | "@babel/core": "7.5.5", |
| | | "@svgr/webpack": "4.3.2", |
| | | "@typescript-eslint/eslint-plugin": "1.13.0", |
| | |
| | | import options from '@/store/options.js' |
| | | |
| | | let mkDataBase = null |
| | | let storUsable = false |
| | | |
| | | if (window.openDatabase) { |
| | | let service = window.GLOB.service ? '-' + window.GLOB.service.replace('/', '') : '' |
| | |
| | | mkDataBase = openDatabase(`mkdb${service}`, '1', 'mk-pc-database', 50 * 1024 * 1024) |
| | | mkDataBase.transaction(tx => { |
| | | tx.executeSql('CREATE TABLE IF NOT EXISTS VERSIONS (version varchar(50), createDate varchar(50), CDefine1 varchar(50), CDefine2 varchar(50), CDefine3 varchar(50))', [], () => { |
| | | |
| | | |
| | | }, () => { |
| | | // eslint-disable-next-line |
| | | throw 'CREATE TABLE ERROR' |
| | |
| | | }) |
| | | }) |
| | | }, () => { |
| | | _reject() |
| | | mkDataBase = null |
| | | _reject() |
| | | return Promise.reject() |
| | | }).then(() => { |
| | | storUsable = true |
| | | _resolve(appVersion) |
| | | }, () => { |
| | | mkDataBase = null |
| | | _reject() |
| | | }) |
| | | } |
| | | |
| | |
| | | _param = JSON.stringify(_param) |
| | | _param = md5(_param) |
| | | |
| | | if (mkDataBase && storUsable) { |
| | | if (mkDataBase) { |
| | | param = this.encryptParam(param) |
| | | |
| | | return new Promise(resolve => { |
| | |
| | | }) |
| | | } |
| | | }, (tx, results) => { |
| | | mkDataBase = null |
| | | console.warn(results) |
| | | |
| | | axios({ |
| | | url: `/webapi/dostars${param.func ? '/' + param.func : ''}`, |
| | | data: param |
| | |
| | | } |
| | | resolve(res) |
| | | }) |
| | | mkDataBase = null |
| | | storUsable = false |
| | | console.warn(results) |
| | | }) |
| | | }) |
| | | }) |
| | |
| | | oriVersion: res.oldVersion, |
| | | newVersion: res.newVersion |
| | | }) |
| | | }, () => { |
| | | console.warn('websql 初始化错误!') |
| | | }) |
| | | }, 1000) |
| | | } |
| | |
| | | }, |
| | | { |
| | | type: 'select', |
| | | key: 'Yaxis', |
| | | label: 'Y-轴', |
| | | initVal: card.Yaxis || [], |
| | | multi: true, // 多选 |
| | | hidden: card.datatype === 'statistics', |
| | | required: true, |
| | | options: yfields |
| | | }, |
| | | { |
| | | type: 'select', |
| | | key: 'InfoType', |
| | | label: '类型', |
| | | initVal: card.InfoType || '', |
| | |
| | | }, |
| | | { |
| | | type: 'select', |
| | | key: 'Yaxis', |
| | | label: 'Y-轴', |
| | | initVal: card.Yaxis || [], |
| | | multi: true, // 多选 |
| | | hidden: card.datatype === 'statistics', |
| | | required: true, |
| | | options: yfields |
| | | }, |
| | | { |
| | | type: 'select', |
| | | key: 'shape', |
| | | label: '形状', |
| | | initVal: card.shape || (shapes[0] && shapes[0].field), |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { fromJS } from 'immutable' |
| | | import { Modal, Form, Row, Col, Select, Icon, Radio, Tooltip, Input, InputNumber, Cascader, Tabs } from 'antd' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Modal, Form, Row, Col, Select, Icon, Radio, Tooltip, Input, InputNumber, Tabs, Button } from 'antd' |
| | | |
| | | import Utils from '@/utils/utils.js' |
| | | import { chartColors } from '@/utils/option.js' |
| | | import { getBarOrLineChartOptionForm } from './formconfig' |
| | | import { minkeColorSystem, colorTransform } from '@/utils/option.js' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import ColorSketch from '@/mob/colorsketch' |
| | | import './index.scss' |
| | | |
| | | const { TabPane } = Tabs |
| | | const EditTable = asyncComponent(() => import('@/templates/zshare/editTable')) |
| | | |
| | | class LineChartDrawerForm extends Component { |
| | | static propTpyes = { |
| | |
| | | state = { |
| | | view: 'normal', |
| | | visible: false, |
| | | disabled: true, |
| | | datatype: '', |
| | | plot: null, |
| | | formlist: null, |
| | | fieldName: null, |
| | | colorOptions: fromJS(minkeColorSystem).toJS().map(option => { |
| | | option.children = option.children.map(cell => { |
| | | let _cell = {} |
| | | _cell.label = <div className={'background ' + cell.value}>{cell.value}</div> |
| | | _cell.value = colorTransform[cell.value] |
| | | |
| | | return _cell |
| | | }) |
| | | return option |
| | | }), |
| | | shapeOptions: [ |
| | | colorColumns: [ |
| | | { |
| | | value: 'line', |
| | | label: '折线', |
| | | children: [ |
| | | { value: 'smooth', label: 'smooth' }, |
| | | { value: 'line', label: 'line' }, |
| | | { value: 'dot', label: 'dot' }, |
| | | { value: 'dash', label: 'dash' }, |
| | | { value: 'hv', label: 'hv' }, |
| | | { value: 'vh', label: 'vh' }, |
| | | { value: 'hvh', label: 'hvh' }, |
| | | { value: 'vhv', label: 'vhv' } |
| | | title: '指标', |
| | | dataIndex: 'label', |
| | | editable: false, |
| | | width: '40%' |
| | | }, |
| | | { |
| | | title: '颜色', |
| | | dataIndex: 'color', |
| | | inputType: 'color', |
| | | editable: true, |
| | | width: '40%', |
| | | render: (text, record) => { |
| | | return (<div style={{width: '80px', height: '23px', background: text}}></div>) |
| | | } |
| | | }, |
| | | ], |
| | | statColorColumns: [ |
| | | { |
| | | title: '指标', |
| | | dataIndex: 'type', |
| | | inputType: 'input', |
| | | editable: true, |
| | | width: '40%' |
| | | }, |
| | | { |
| | | title: '颜色', |
| | | dataIndex: 'color', |
| | | inputType: 'color', |
| | | editable: true, |
| | | width: '40%', |
| | | render: (text, record) => { |
| | | return (<div style={{width: '80px', height: '23px', background: text}}></div>) |
| | | } |
| | | }, |
| | | ], |
| | | cusColumns: [ |
| | | { |
| | | title: '指标', |
| | | dataIndex: 'name', |
| | | editable: false, |
| | | width: '20%' |
| | | }, |
| | | { |
| | | title: '形状', |
| | | dataIndex: 'shape', |
| | | inputType: 'cascader', |
| | | editable: true, |
| | | width: '20%', |
| | | render: (text, record) => { |
| | | return text.join(' / ').replace('line', '折线').replace('bar', '柱形') |
| | | }, |
| | | options: [ |
| | | { |
| | | value: 'line', |
| | | label: '折线', |
| | | children: [ |
| | | { value: 'smooth', label: 'smooth' }, |
| | | { value: 'line', label: 'line' }, |
| | | { value: 'dot', label: 'dot' }, |
| | | { value: 'dash', label: 'dash' }, |
| | | { value: 'hv', label: 'hv' }, |
| | | { value: 'vh', label: 'vh' }, |
| | | { value: 'hvh', label: 'hvh' }, |
| | | { value: 'vhv', label: 'vhv' } |
| | | ] |
| | | }, |
| | | { |
| | | value: 'bar', |
| | | label: '柱形', |
| | | children: [ |
| | | { value: 'rect', label: 'rect' }, |
| | | { value: 'hollow-rect', label: 'hollow-rect' }, |
| | | { value: 'line', label: 'line' }, |
| | | { value: 'tick', label: 'tick' }, |
| | | { value: 'funnel', label: 'funnel' }, |
| | | { value: 'pyramid', label: 'pyramid' } |
| | | ], |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | value: 'bar', |
| | | label: '柱形', |
| | | children: [ |
| | | { value: 'rect', label: 'rect' }, |
| | | { value: 'hollow-rect', label: 'hollow-rect' }, |
| | | { value: 'line', label: 'line' }, |
| | | { value: 'tick', label: 'tick' }, |
| | | { value: 'funnel', label: 'funnel' }, |
| | | { value: 'pyramid', label: 'pyramid' } |
| | | title: '坐标轴', |
| | | dataIndex: 'axis', |
| | | inputType: 'select', |
| | | editable: true, |
| | | width: '20%', |
| | | options: [ |
| | | { value: 'true', text: '显示'}, |
| | | { value: 'false', text: '隐藏'} |
| | | ], |
| | | } |
| | | render: (text, record) => { |
| | | let trans = {'true': '显示', 'false': '隐藏'} |
| | | return trans[text] || '隐藏' |
| | | } |
| | | }, |
| | | { |
| | | title: '标注', |
| | | dataIndex: 'label', |
| | | inputType: 'select', |
| | | editable: true, |
| | | width: '20%', |
| | | options: [ |
| | | { value: 'true', text: '显示'}, |
| | | { value: 'false', text: '隐藏'} |
| | | ], |
| | | render: (text, record) => { |
| | | let trans = {'true': '显示', 'false': '隐藏'} |
| | | return trans[text] || '隐藏' |
| | | } |
| | | }, |
| | | ] |
| | | } |
| | | |
| | |
| | | this.setState({ |
| | | visible: true, |
| | | view: 'normal', |
| | | disabled: config.plot.datatype === 'statistics', |
| | | datatype: config.plot.datatype || 'query', |
| | | fieldName: fieldName, |
| | | plot: fromJS(config.plot).toJS(), |
| | | formlist: getBarOrLineChartOptionForm(config.plot, config.columns, sysRoles, MenuType) |
| | |
| | | |
| | | if (key === 'datatype') { |
| | | this.setState({ |
| | | disabled: val === 'statistics', |
| | | datatype: val, |
| | | formlist: formlist.map(item => { |
| | | if (['Yaxis'].includes(item.key)) { |
| | | item.hidden = val === 'statistics' |
| | |
| | | return fields |
| | | } |
| | | |
| | | getCustomFields = () => { |
| | | const { getFieldDecorator } = this.props.form |
| | | const { plot, fieldName, enabled, colorOptions, shapeOptions } = this.state |
| | | const fields = [] |
| | | |
| | | if (!plot.customs) return null |
| | | |
| | | fields.push(<Col span={12} key="enabled"> |
| | | <Form.Item label="是否启用" style={{marginBottom: 10}}> |
| | | {getFieldDecorator('enabled', { |
| | | initialValue: plot.enabled || 'false' |
| | | })( |
| | | <Radio.Group onChange={this.enabledChange}> |
| | | <Radio value="true">是</Radio> |
| | | <Radio value="false">否</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col>) |
| | | |
| | | plot.customs.forEach((item, i) => { |
| | | fields.push(<Col span={24} key={'field' + i}> |
| | | <p className="field-title">{fieldName[item.field]}</p> |
| | | </Col>) |
| | | fields.push(<Col span={12} key={'shape' + i}> |
| | | <Form.Item label="形状"> |
| | | {getFieldDecorator(item.field + '$shape', { |
| | | initialValue: item.$shape, |
| | | rules: [ |
| | | { |
| | | required: enabled === 'true', |
| | | message: this.props.dict['form.required.select'] + '形状!' |
| | | } |
| | | ] |
| | | })( |
| | | <Cascader |
| | | disabled={enabled === 'false'} |
| | | options={shapeOptions} |
| | | placeholder="" |
| | | displayRender={(label, selectedOptions) => selectedOptions[0] ? selectedOptions[0].label + ' / ' + selectedOptions[1].value : ''} |
| | | /> |
| | | )} |
| | | </Form.Item> |
| | | </Col>) |
| | | fields.push(<Col span={12} key={'color' + i}> |
| | | <Form.Item label="颜色"> |
| | | {getFieldDecorator(item.field + '$color', { |
| | | initialValue: item.$color, |
| | | rules: [ |
| | | { |
| | | required: enabled === 'true', |
| | | message: this.props.dict['form.required.select'] + '颜色!' |
| | | } |
| | | ] |
| | | })( |
| | | <Cascader |
| | | disabled={enabled === 'false'} |
| | | options={colorOptions} |
| | | placeholder="" |
| | | getPopupContainer={() => document.getElementById('chart-custom-drawer-form')} |
| | | displayRender={(label, selectedOptions) => selectedOptions[0] ? <div style={{background: selectedOptions[1].value, width: '20px', height: '20px'}}></div> : ''} |
| | | /> |
| | | )} |
| | | </Form.Item> |
| | | </Col>) |
| | | fields.push(<Col span={12} key={'axis' + i}> |
| | | <Form.Item label="坐标轴"> |
| | | {getFieldDecorator(item.field + '$axis', { |
| | | initialValue: item.axis |
| | | })( |
| | | <Radio.Group disabled={enabled === 'false'} onChange={this.axisChange}> |
| | | <Radio value="left">左侧</Radio> |
| | | <Radio value="right">右侧</Radio> |
| | | <Radio value="unset">不显示</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col>) |
| | | fields.push(<Col span={12} key={'label' + i}> |
| | | <Form.Item label="标注-值"> |
| | | {getFieldDecorator(item.field + '$label', { |
| | | initialValue: item.label |
| | | })( |
| | | <Radio.Group disabled={enabled === 'false'}> |
| | | <Radio value="true">显示</Radio> |
| | | <Radio value="false">隐藏</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col>) |
| | | }) |
| | | |
| | | return fields |
| | | } |
| | | |
| | | axisChange = (e) => { |
| | | enabledChange = (e) => { |
| | | const { plot } = this.state |
| | | let val = e.target.value |
| | | let fieldvalue = {} |
| | | |
| | | plot.customs.forEach(item => { |
| | | if (this.props.form.getFieldValue(item.field + '$axis') === val) { |
| | | fieldvalue[item.field + '$axis'] = 'unset' |
| | | } |
| | | }) |
| | | |
| | | this.props.form.setFieldsValue(fieldvalue) |
| | | } |
| | | |
| | | enabledChange = (e) => { |
| | | let val = e.target.value |
| | | |
| | | this.setState({enabled: val}) |
| | | this.setState({plot: {...plot, enabled: val}}) |
| | | } |
| | | |
| | | onSubmit = () => { |
| | | const { config } = this.props |
| | | const { plot, view, datatype } = this.state |
| | | const { plot, view } = this.state |
| | | |
| | | if (view !== 'custom') { |
| | | if (view === 'normal') { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | let _plot = {...plot, ...values} |
| | | |
| | | if (datatype === 'query') { |
| | | if (_plot.enabled === 'true') { |
| | | if (_plot.customs.map(_cell => _cell.field).sort().toString() !== _plot.Yaxis.sort().toString()) { |
| | | _plot.customs = null |
| | | _plot.enabled = 'false' |
| | | } |
| | | } |
| | | } else { |
| | | _plot.customs = null |
| | | if (values.datatype === 'statistics' || values.datatype !== plot.datatype) { |
| | | _plot.enabled = 'false' |
| | | } else if (!values.Yaxis || !plot.Yaxis || !is(fromJS(values.Yaxis), fromJS(plot.Yaxis))) { |
| | | _plot.enabled = 'false' |
| | | _plot.colors = null |
| | | } |
| | | |
| | | |
| | | if (values.datatype !== plot.datatype) { |
| | | _plot.colors = null |
| | | } |
| | | |
| | | this.setState({ |
| | | plot: _plot, |
| | | visible: false |
| | |
| | | } |
| | | }) |
| | | } else { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | let _plot = {...plot, enabled: values.enabled} |
| | | |
| | | if (_plot.enabled === 'true') { |
| | | _plot.customs = _plot.Yaxis.map(field => { |
| | | let _item = {field: field} |
| | | |
| | | _item.$shape = values[field + '$shape'] |
| | | _item.chartType = _item.$shape[0] |
| | | _item.shape = _item.$shape[1] |
| | | |
| | | _item.$color = values[field + '$color'] |
| | | _item.color = _item.$color[1] |
| | | |
| | | _item.axis = values[field + '$axis'] |
| | | |
| | | _item.label = values[field + '$label'] |
| | | |
| | | return _item |
| | | }) |
| | | } else { |
| | | _plot.customs = null |
| | | } |
| | | |
| | | this.setState({ |
| | | plot: _plot, |
| | | visible: false |
| | | }) |
| | | |
| | | this.props.plotchange(_plot) |
| | | } |
| | | this.setState({ |
| | | visible: false |
| | | }) |
| | | this.props.plotchange({...config, plot}) |
| | | } |
| | | } |
| | | |
| | | changeTab = (tab) => { |
| | | const { config } = this.props |
| | | const { plot } = this.state |
| | | const { plot, view } = this.state |
| | | |
| | | if (tab === 'custom') { |
| | | if (view === 'normal') { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | let _plot = {...plot, ...values} |
| | | |
| | | if (_plot.enabled !== 'true' || _plot.customs.map(_cell => _cell.field).sort().toString() !== _plot.Yaxis.sort().toString()) { |
| | | if (values.datatype === 'statistics' || values.datatype !== plot.datatype) { |
| | | _plot.enabled = 'false' |
| | | _plot.customs = _plot.Yaxis.map((field, i) => { |
| | | let _item = {field: field} |
| | | _item.$shape = [_plot.chartType, _plot.shape] |
| | | _item.$color = [] |
| | | _item.axis = i === 0 ? 'left' : 'unset' |
| | | _item.label = _plot.label |
| | | |
| | | return _item |
| | | _plot.customs = [] |
| | | } else if (!values.Yaxis || !plot.Yaxis || !is(fromJS(values.Yaxis), fromJS(plot.Yaxis))) { |
| | | _plot.enabled = 'false' |
| | | _plot.customs = [] |
| | | _plot.colors = null |
| | | } |
| | | |
| | | let labels = {} |
| | | config.columns.forEach(col => { |
| | | labels[col.field] = col.label |
| | | }) |
| | | |
| | | if (values.datatype !== 'statistics' && (!_plot.customs || _plot.customs.length === 0)) { |
| | | _plot.customs = _plot.Yaxis.map((item, i) => { |
| | | return { |
| | | uuid: Utils.getuuid(), |
| | | type: item, |
| | | name: labels[item] || item, |
| | | axis: i === 0 ? 'true' : 'false', |
| | | label: 'false', |
| | | shape: _plot.chartType === 'bar' ? ['bar', 'rect'] : ['line', 'smooth'] |
| | | } |
| | | }) |
| | | } |
| | | |
| | | if (values.datatype !== plot.datatype || !_plot.colors) { |
| | | _plot.colors = [] |
| | | if (_plot.datatype === 'query') { |
| | | let limit = chartColors.length |
| | | |
| | | _plot.colors = _plot.Yaxis.map((item, i) => { |
| | | return { |
| | | uuid: Utils.getuuid(), |
| | | type: item, |
| | | label: labels[item] || item, |
| | | color: chartColors[i % limit] |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | |
| | | this.setState({ |
| | | enabled: _plot.enabled || 'false', |
| | | datatype: _plot.datatype, |
| | | plot: _plot, |
| | | view: tab |
| | | }) |
| | | } |
| | | }) |
| | | } else { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | let _values = {enabled: values.enabled} |
| | | |
| | | if (values.enabled === 'true') { |
| | | let _customs = [] |
| | | plot.Yaxis.forEach(field => { |
| | | let _item = {field: field} |
| | | |
| | | _item.$shape = values[field + '$shape'] |
| | | _item.chartType = _item.$shape[0] |
| | | _item.shape = _item.$shape[1] |
| | | |
| | | _item.$color = values[field + '$color'] |
| | | _item.color = _item.$color[1] |
| | | |
| | | _item.axis = values[field + '$axis'] |
| | | _item.label = values[field + '$label'] |
| | | |
| | | _customs.push(_item) |
| | | }) |
| | | |
| | | _values.customs = _customs |
| | | } else { |
| | | _values.customs = null |
| | | } |
| | | |
| | | let _plot = {...plot, ..._values} |
| | | |
| | | this.setState({ |
| | | plot: _plot, |
| | | view: tab, |
| | | formlist: getBarOrLineChartOptionForm(_plot, config.columns) |
| | | }) |
| | | } |
| | | this.setState({ |
| | | view: tab |
| | | }) |
| | | } |
| | | } |
| | | |
| | | addColor = () => { |
| | | let plot = fromJS(this.state.plot).toJS() |
| | | plot.colors = plot.colors || [] |
| | | |
| | | plot.colors.push({ |
| | | uuid: Utils.getuuid(), |
| | | type: `指标${plot.colors.length}`, |
| | | color: 'rgb(91, 143, 249)' |
| | | }) |
| | | |
| | | this.setState({plot}) |
| | | } |
| | | |
| | | changeColor = (colors) => { |
| | | const { plot } = this.state |
| | | |
| | | this.setState({plot: {...plot, colors}}) |
| | | } |
| | | |
| | | changeCustom = (customs) => { |
| | | const { plot } = this.state |
| | | |
| | | this.setState({plot: {...plot, customs}}) |
| | | } |
| | | |
| | | render() { |
| | | const { view, visible, disabled } = this.state |
| | | const { view, visible, datatype, plot, colorColumns, statColorColumns, cusColumns } = this.state |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | |
| | | > |
| | | <Tabs activeKey={view} className="menu-chart-edit-box" onChange={this.changeTab}> |
| | | <TabPane tab="基础设置" key="normal"> |
| | | {view === 'normal' ? <Form {...formItemLayout}> |
| | | <Form {...formItemLayout}> |
| | | <Row gutter={16}>{this.getFields()}</Row> |
| | | </Form> : null} |
| | | </Form> |
| | | </TabPane> |
| | | <TabPane tab="自定义设置" disabled={disabled} key="custom"> |
| | | {view === 'custom' ? <Form {...formItemLayout}> |
| | | <Row gutter={16}>{this.getCustomFields()}</Row> |
| | | </Form> : null} |
| | | </TabPane> |
| | | {plot ? <TabPane tab="颜色设置" key="color"> |
| | | <div> |
| | | {datatype === 'statistics' ? <Button className="color-add mk-green" onClick={this.addColor}>{this.props.dict['model.add']}</Button> : null} |
| | | {datatype === 'statistics' ? <EditTable data={plot.colors || []} columns={statColorColumns} onChange={this.changeColor}/> : null} |
| | | {datatype !== 'statistics' ? <EditTable actions={['edit']} data={plot.colors || []} columns={colorColumns} onChange={this.changeColor}/> : null} |
| | | </div> |
| | | </TabPane> : null} |
| | | {plot ? <TabPane tab="自定义设置" disabled={datatype === 'statistics'} key="custom"> |
| | | <Col span={12}> |
| | | <Form {...formItemLayout}> |
| | | <Form.Item label="是否启用" style={{marginBottom: 10}}> |
| | | <Radio.Group value={plot.enabled || 'false'} onChange={this.enabledChange}> |
| | | <Radio value="true">是</Radio> |
| | | <Radio value="false">否</Radio> |
| | | </Radio.Group> |
| | | </Form.Item> |
| | | </Form> |
| | | </Col> |
| | | <Col style={{fontSize: '12px', color: '#757575', paddingLeft: '10px'}} span={24}>注:使用自定义设置时,显示的坐标轴第一个在左侧,第二个在右侧,多余的不生效;柱形图只可以添加一个(设置多个时,第一个生效)。</Col> |
| | | <EditTable actions={['edit', 'up', 'down']} data={plot.customs || []} columns={cusColumns} onChange={this.changeCustom}/> |
| | | </TabPane> : null} |
| | | </Tabs> |
| | | </Modal> |
| | | </div> |
| | |
| | | top: 50px; |
| | | .ant-modal-body { |
| | | max-height: calc(100vh - 190px); |
| | | min-height: 50vh; |
| | | padding-top: 10px; |
| | | .menu-chart-edit-box { |
| | | .anticon-question-circle { |
| | |
| | | .color-sketch-block { |
| | | position: relative; |
| | | top: 5px; |
| | | width: 240px; |
| | | } |
| | | .color-add { |
| | | float: right; |
| | | margin-bottom: 10px; |
| | | position: relative; |
| | | z-index: 1; |
| | | } |
| | | } |
| | | } |
| | |
| | | import asyncIconComponent from '@/utils/asyncIconComponent' |
| | | |
| | | import Utils from '@/utils/utils.js' |
| | | import { chartColors } from '@/utils/option.js' |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | import './index.scss' |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description 折线图 |
| | | */ |
| | | linerender = () => { |
| | | 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 = {} |
| | | card.columns.forEach(col => { |
| | | if (col.field) { |
| | | transfield[col.field] = col.label |
| | | } |
| | | }) |
| | | |
| | | let X_axis = plot.Xaxis || 'x' |
| | | let Y_axis = plot.Yaxis || ['y'] |
| | | |
| | |
| | | if (plot.enabled !== 'true') { |
| | | const ds = new DataSet() |
| | | const dv = ds.createView().source(data) |
| | | let transfield = {} |
| | | card.columns.forEach(col => { |
| | | if (col.field) { |
| | | transfield[col.field] = col.label |
| | | } |
| | | }) |
| | | |
| | | dv.transform({ |
| | | type: 'fold', |
| | |
| | | |
| | | 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.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, { |
| | |
| | | }) |
| | | } |
| | | chart.scale('value', { |
| | | nice: true |
| | | nice: true, |
| | | range: [0, 0.93] |
| | | }) |
| | | |
| | | if (!plot.legend || plot.legend === 'hidden') { |
| | |
| | | } else { |
| | | chart.legend({ |
| | | position: plot.legend, |
| | | itemName: { |
| | | style: { |
| | | fill: color, |
| | | } |
| | | } |
| | | itemName: { style: { fill: color } } |
| | | }) |
| | | } |
| | | |
| | |
| | | radius: 0.8 |
| | | }) |
| | | } |
| | | |
| | | let colors = new Map() |
| | | let colorIndex = 0 |
| | | |
| | | if (plot.colors && plot.colors.length > 0) { |
| | | plot.colors.forEach(item => { |
| | | if (!colors.has(transfield[item.type])) { |
| | | colors.set(transfield[item.type], item.color) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | let _chart = chart |
| | | .line() |
| | | .position(`${X_axis}*value`) |
| | | .color('key') |
| | | .shape(plot.shape || 'smooth') |
| | | .tooltip(`${X_axis}*value`, (name, value) => { |
| | | if (plot.show === 'percent') { |
| | | value = value + '%' |
| | | } |
| | | return { |
| | | name: name, |
| | | value: value |
| | | } |
| | | }) |
| | | |
| | | if (plot.colors && plot.colors.length > 0) { |
| | | let limit = chartColors.length |
| | | _chart.color('key', (key) => { |
| | | if (colors.get(key)) { |
| | | return colors.get(key) |
| | | } else { |
| | | colors.set(key, chartColors[colorIndex % limit]) |
| | | colorIndex++ |
| | | } |
| | | }) |
| | | } else { |
| | | _chart.color('key') |
| | | } |
| | | if (plot.label === 'true') { |
| | | _chart.label('value') |
| | | _chart.label('value', (value) => { |
| | | if (plot.show === 'percent') { |
| | | value = value + '%' |
| | | } |
| | | return { |
| | | content: value, |
| | | style: { |
| | | fill: color |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | if (plot.point === 'true') { |
| | |
| | | } |
| | | chart.render() |
| | | } else { |
| | | this.customrender(data, transfield) |
| | | this.customrender(data) |
| | | } |
| | | } |
| | | |
| | | customrender = (data, transfield) => { |
| | | const { card } = this.state |
| | | /** |
| | | * @description 自定义图 |
| | | */ |
| | | customrender = (data) => { |
| | | let card = fromJS(this.state.card).toJS() |
| | | let plot = {...card.plot, height: card.plot.height - 80} // 去除title所占空间 |
| | | let color = plot.color || 'rgba(0, 0, 0, 0.85)' |
| | | |
| | | let barfields = [] |
| | | let fields = [] |
| | | let legends = [] |
| | | let transfield = {} |
| | | |
| | | card.columns.forEach(col => { |
| | | if (col.field) { |
| | | transfield[col.field] = col.label |
| | | } |
| | | }) |
| | | |
| | | let colors = new Map() |
| | | let colorIndex = 0 |
| | | let limit = chartColors.length |
| | | |
| | | if (plot.colors && plot.colors.length > 0) { |
| | | plot.colors.forEach(item => { |
| | | if (!colors.has(item.type)) { |
| | | colors.set(item.type, item.color) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | let axisIndex = 0 |
| | | let hasBar = false |
| | | |
| | | 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 |
| | | item.name = transfield[item.type] || item.type |
| | | item.chartType = item.shape ? (item.shape[0] || 'bar') : 'bar' |
| | | item.shape = item.shape ? (item.shape[1] || '') : '' |
| | | |
| | | if (colors.get(item.type)) { |
| | | item.color = colors.get(item.type) |
| | | } else { |
| | | item.index = 2 |
| | | item.color = chartColors[colorIndex % limit] |
| | | colorIndex++ |
| | | } |
| | | |
| | | if (item.chartType === 'bar') { |
| | | barfields.push(item.field) |
| | | fields.unshift(item) |
| | | if (item.chartType === 'bar' && !hasBar) { |
| | | hasBar = true |
| | | } else if (item.chartType === 'bar') { |
| | | item.chartType = 'line' |
| | | item.shape = 'smooth' |
| | | } |
| | | |
| | | if (item.axis === 'true' && axisIndex < 2) { |
| | | if (axisIndex === 0) { |
| | | item.axis = { grid: {style: { fill: color }}, title: { style: { fill: color } }, label: {style: { fill: color }} } |
| | | fields.unshift(item) |
| | | } else { |
| | | item.axis = { grid: null, title: {style: { fill: color }}, label: {style: { fill: color }} } |
| | | fields.splice(1, 0, item) |
| | | } |
| | | axisIndex++ |
| | | } else { |
| | | item.axis = { grid: null, title: null, label: null } |
| | | fields.push(item) |
| | | } |
| | | |
| | | |
| | | legends.push({ |
| | | value: item.name, |
| | | name: item.name, |
| | |
| | | }) |
| | | }) |
| | | |
| | | 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] |
| | | row[line.name] = row[line.type] |
| | | }) |
| | | return row |
| | | } |
| | | }) |
| | | |
| | | const chart = new Chart({ |
| | | container: plot.uuid, |
| | | container: card.uuid, |
| | | autoFit: true, |
| | | height: plot.height || 400 |
| | | }) |
| | | |
| | | 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, |
| | | } |
| | | } |
| | | }) |
| | | chart.axis(plot.Xaxis, { label: { style: { fill: color } }, line: { style: { fill: color } } }) |
| | | |
| | | if (plot.coordinate !== 'polar' && barfields.length === 0) { |
| | | if (!hasBar) { |
| | | chart.scale(plot.Xaxis, { |
| | | range: [0, 1] |
| | | }) |
| | |
| | | custom: true, |
| | | position: plot.legend, |
| | | items: legends, |
| | | itemName: { |
| | | style: { |
| | | fill: color, |
| | | } |
| | | } |
| | | itemName: { style: { fill: color } } |
| | | }) |
| | | } |
| | | |
| | |
| | | }) |
| | | } |
| | | |
| | | 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 |
| | | }) |
| | | } |
| | | fields.forEach(item => { |
| | | chart.axis(item.name, item.axis) |
| | | |
| | | chart.scale(item.name, { |
| | | nice: true, |
| | | range: [0, 0.93] |
| | | }) |
| | | |
| | | if (item.chartType === 'bar') { |
| | | let _chart = chart |
| | | .interval() |
| | | .position(`${plot.Xaxis}*${item.name}`) |
| | | .color(item.color) |
| | | .shape(item.shape) |
| | | .tooltip(`${plot.Xaxis}*${item.name}`, (name, value) => { |
| | | if (plot.show === 'percent') { |
| | | value = value + '%' |
| | | } |
| | | return { |
| | | name: name, |
| | | value: value |
| | | } |
| | | }) |
| | | |
| | | if (plot.barSize) { |
| | | _chart.size(plot.barSize || 35) |
| | | } |
| | | if (item.label === 'true') { |
| | | _chart.label(item.name) |
| | | _chart.label(item.name, (value) => { |
| | | if (plot.show === 'percent') { |
| | | value = value + '%' |
| | | } |
| | | return { |
| | | content: value, |
| | | style: { |
| | | fill: color |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | } else if (item.chartType === 'line') { |
| | | let _chart = chart |
| | |
| | | .position(`${plot.Xaxis}*${item.name}`) |
| | | .color(item.color) |
| | | .shape(item.shape) |
| | | .tooltip(`${plot.Xaxis}*${item.name}`, (name, value) => { |
| | | if (plot.show === 'percent') { |
| | | value = value + '%' |
| | | } |
| | | return { |
| | | name: name, |
| | | value: value |
| | | } |
| | | }) |
| | | |
| | | if (item.label === 'true') { |
| | | _chart.label(item.name) |
| | | _chart.label(item.name, (value) => { |
| | | if (plot.show === 'percent') { |
| | | value = value + '%' |
| | | } |
| | | return { |
| | | content: value, |
| | | style: { |
| | | fill: color |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | if (plot.point === 'true') { |
| | |
| | | chart.render() |
| | | } |
| | | |
| | | /** |
| | | * @description 柱形图 |
| | | */ |
| | | barrender = () => { |
| | | const { card } = this.state |
| | | 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 => { |
| | | if (col.field) { |
| | | transfield[col.field] = col.label |
| | | } |
| | | }) |
| | | let X_axis = plot.Xaxis || 'x' |
| | | let Y_axis = plot.Yaxis || ['y'] |
| | | |
| | |
| | | if (plot.enabled !== 'true') { |
| | | const ds = new DataSet() |
| | | const dv = ds.createView().source(data) |
| | | let transfield = {} |
| | | |
| | | card.columns.forEach(col => { |
| | | if (col.field) { |
| | | transfield[col.field] = col.label |
| | | } |
| | | }) |
| | | |
| | | dv.transform({ |
| | | type: 'fold', |
| | |
| | | |
| | | 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.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 |
| | | nice: true, |
| | | range: [0, 0.93] |
| | | }) |
| | | |
| | | if (!plot.legend || plot.legend === 'hidden') { |
| | |
| | | } else { |
| | | chart.legend({ |
| | | position: plot.legend, |
| | | itemName: { |
| | | style: { |
| | | fill: color, |
| | | } |
| | | } |
| | | itemName: { style: { fill: color } } |
| | | }) |
| | | } |
| | | |
| | |
| | | radius: 0.8 |
| | | }) |
| | | } |
| | | |
| | | let colors = new Map() |
| | | let colorIndex = 0 |
| | | |
| | | if (plot.colors && plot.colors.length > 0) { |
| | | plot.colors.forEach(item => { |
| | | if (!colors.has(transfield[item.type])) { |
| | | colors.set(transfield[item.type], item.color) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | if (plot.adjust !== 'stack') { |
| | | let _chart = chart |
| | | .interval() |
| | | .position(`${X_axis}*value`) |
| | | .color('key') |
| | | .adjust([ |
| | | { |
| | | type: 'dodge', |
| | |
| | | } |
| | | ]) |
| | | .shape(plot.shape || 'rect') |
| | | |
| | | .tooltip(`${X_axis}*value`, (name, value) => { |
| | | if (plot.show === 'percent') { |
| | | value = value + '%' |
| | | } |
| | | return { |
| | | name: name, |
| | | value: value |
| | | } |
| | | }) |
| | | |
| | | if (plot.colors && plot.colors.length > 0) { |
| | | let limit = chartColors.length |
| | | _chart.color('key', (key) => { |
| | | if (colors.get(key)) { |
| | | return colors.get(key) |
| | | } else { |
| | | colors.set(key, chartColors[colorIndex % limit]) |
| | | colorIndex++ |
| | | } |
| | | }) |
| | | } else { |
| | | _chart.color('key') |
| | | } |
| | | if (plot.label === 'true') { |
| | | _chart.label('value') |
| | | _chart.label('value', (value) => { |
| | | if (plot.show === 'percent') { |
| | | value = value + '%' |
| | | } |
| | | return { |
| | | content: value, |
| | | style: { |
| | | fill: color |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | if (plot.barSize || plot.correction) { |
| | |
| | | let _chart = chart |
| | | .interval() |
| | | .position(`${X_axis}*value`) |
| | | .color('key') |
| | | .adjust('stack') |
| | | .shape(plot.shape || 'rect') |
| | | .tooltip(`${X_axis}*value`, (name, value) => { |
| | | if (plot.show === 'percent') { |
| | | value = value + '%' |
| | | } |
| | | return { |
| | | name: name, |
| | | value: value |
| | | } |
| | | }) |
| | | |
| | | if (plot.colors && plot.colors.length > 0) { |
| | | let limit = chartColors.length |
| | | _chart.color('key', (key) => { |
| | | if (colors.get(key)) { |
| | | return colors.get(key) |
| | | } else { |
| | | colors.set(key, chartColors[colorIndex % limit]) |
| | | colorIndex++ |
| | | } |
| | | }) |
| | | } else { |
| | | _chart.color('key') |
| | | } |
| | | if (plot.label === 'true') { |
| | | _chart.label('value') |
| | | _chart.label('value', (value) => { |
| | | if (plot.show === 'percent') { |
| | | value = value + '%' |
| | | } |
| | | return { |
| | | content: value, |
| | | style: { |
| | | fill: color |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | if (plot.barSize || plot.correction) { |
| | |
| | | |
| | | chart.render() |
| | | } else { |
| | | this.customrender(data, transfield) |
| | | this.customrender(data) |
| | | } |
| | | } |
| | | |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { fromJS } from 'immutable' |
| | | import { Modal, Form, Row, Col, Select, Icon, Radio, Tooltip, Input, InputNumber } from 'antd' |
| | | import { Modal, Form, Row, Col, Select, Icon, Radio, Tooltip, Input, InputNumber, Tabs, Button } from 'antd' |
| | | |
| | | import Utils from '@/utils/utils.js' |
| | | import { getPieChartOptionForm } from './formconfig' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import ColorSketch from '@/mob/colorsketch' |
| | | import './index.scss' |
| | | |
| | | const { TabPane } = Tabs |
| | | |
| | | const EditTable = asyncComponent(() => import('@/templates/zshare/editTable')) |
| | | |
| | | class LineChartDrawerForm extends Component { |
| | | static propTpyes = { |
| | |
| | | state = { |
| | | visible: false, |
| | | plot: null, |
| | | formlist: null |
| | | formlist: null, |
| | | view: 'normal', |
| | | colorColumns: [ |
| | | { |
| | | title: '指标', |
| | | dataIndex: 'label', |
| | | inputType: 'input', |
| | | editable: true, |
| | | width: '40%' |
| | | }, |
| | | { |
| | | title: '颜色', |
| | | dataIndex: 'color', |
| | | inputType: 'color', |
| | | editable: true, |
| | | width: '40%', |
| | | render: (text, record) => { |
| | | return (<div style={{width: '80px', height: '23px', background: text}}></div>) |
| | | } |
| | | }, |
| | | ] |
| | | } |
| | | |
| | | showDrawer = () => { |
| | |
| | | |
| | | this.setState({ |
| | | visible: true, |
| | | view: 'normal', |
| | | plot: fromJS(config.plot).toJS(), |
| | | formlist: getPieChartOptionForm(config.plot, config.columns, sysRoles, MenuType) |
| | | }) |
| | |
| | | |
| | | onSubmit = () => { |
| | | const { config } = this.props |
| | | const { plot } = this.state |
| | | const { plot, view } = this.state |
| | | |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | let _plot = {...plot, ...values} |
| | | |
| | | this.setState({ |
| | | plot: _plot, |
| | | visible: false |
| | | }) |
| | | if (view === 'normal') { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | let _plot = {...plot, ...values} |
| | | |
| | | this.setState({ |
| | | plot: _plot, |
| | | visible: false |
| | | }) |
| | | |
| | | this.props.plotchange({...config, plot: _plot}) |
| | | } |
| | | }) |
| | | } else { |
| | | this.setState({ |
| | | visible: false |
| | | }) |
| | | |
| | | this.props.plotchange({...config, plot: _plot}) |
| | | } |
| | | }) |
| | | this.props.plotchange({...config, plot: plot}) |
| | | } |
| | | } |
| | | |
| | | changeTab = (tab) => { |
| | | const { plot } = this.state |
| | | |
| | | if (tab === 'color') { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | let _plot = {...plot, ...values} |
| | | |
| | | this.setState({ |
| | | plot: _plot, |
| | | view: tab |
| | | }) |
| | | } |
| | | }) |
| | | } else { |
| | | this.setState({ |
| | | view: tab |
| | | }) |
| | | } |
| | | } |
| | | |
| | | addColor = () => { |
| | | let plot = fromJS(this.state.plot).toJS() |
| | | plot.colors = plot.colors || [] |
| | | |
| | | plot.colors.push({ |
| | | uuid: Utils.getuuid(), |
| | | label: `指标${plot.colors.length}`, |
| | | color: 'rgb(91, 143, 249)' |
| | | }) |
| | | |
| | | this.setState({plot}) |
| | | } |
| | | |
| | | changeColor = (colors) => { |
| | | const { plot } = this.state |
| | | |
| | | this.setState({plot: {...plot, colors}}) |
| | | } |
| | | |
| | | render() { |
| | | const { visible } = this.state |
| | | const { visible, plot, colorColumns, view } = this.state |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | |
| | | onCancel={() => { this.setState({ visible: false }) }} |
| | | destroyOnClose |
| | | > |
| | | <Form {...formItemLayout}> |
| | | <Row gutter={16}>{this.getFields()}</Row> |
| | | </Form> |
| | | <Tabs activeKey={view} className="menu-chart-edit-box" onChange={this.changeTab}> |
| | | <TabPane tab="基础设置" key="normal"> |
| | | <Form {...formItemLayout}> |
| | | <Row gutter={16}>{this.getFields()}</Row> |
| | | </Form> |
| | | </TabPane> |
| | | {plot ? <TabPane tab="颜色设置" key="color"> |
| | | <div> |
| | | <Button className="color-add mk-green" onClick={this.addColor}>{this.props.dict['model.add']}</Button> |
| | | <EditTable data={plot.colors || []} columns={colorColumns} onChange={this.changeColor}/> |
| | | </div> |
| | | </TabPane> : null} |
| | | </Tabs> |
| | | |
| | | </Modal> |
| | | </div> |
| | | ); |
| | |
| | | .ant-modal { |
| | | top: 50px; |
| | | .ant-modal-body { |
| | | min-height: 50vh; |
| | | max-height: calc(100vh - 190px); |
| | | padding-top: 10px; |
| | | .anticon-question-circle { |
| | |
| | | .color-sketch-block { |
| | | position: relative; |
| | | top: 5px; |
| | | width: 240px; |
| | | } |
| | | .color-add { |
| | | float: right; |
| | | margin-bottom: 10px; |
| | | position: relative; |
| | | z-index: 1; |
| | | } |
| | | } |
| | | } |
| | |
| | | return ( |
| | | <Form {...formItemLayout} className="verify-form" id="verifycard1"> |
| | | <Row gutter={24}> |
| | | <Col span={7}> |
| | | <Col span={6}> |
| | | <Form.Item label={'名称'}> |
| | | {getFieldDecorator('label', { |
| | | initialValue: '', |
| | |
| | | })(<Input placeholder="" autoComplete="off" />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={7}> |
| | | <Col span={6}> |
| | | <Form.Item label={'字段'}> |
| | | {getFieldDecorator('field', { |
| | | initialValue: '', |
| | |
| | | })(<Input placeholder="" autoComplete="off" />)} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={7}> |
| | | <Col span={6}> |
| | | <Form.Item label={'数据类型'}> |
| | | {getFieldDecorator('datatype', { |
| | | initialValue: '', |
| | |
| | | {setting.tableName} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | <Col span={16}> |
| | | <Col span={8}> |
| | | <Form.Item label={'报错字段'} style={{margin: 0}}> |
| | | ErrorCode, retmsg |
| | | </Form.Item> |
| | |
| | | id, bid, loginuid, sessionuid, userid, appkey, time_id{usefulFields ? ', ' + usefulFields : ''} |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={10}> |
| | | <Form.Item label={'快捷添加'} style={{marginBottom: 0}}> |
| | | <Col span={10} style={{width: '43%'}}> |
| | | <Form.Item label={'快捷添加'} labelCol={{xs: { span: 24 }, sm: { span: 6 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 18 }} } style={{marginBottom: 0}}> |
| | | <Select |
| | | showSearch |
| | | filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} |
| | |
| | | |
| | | let _setting = fromJS(config.setting).toJS() |
| | | |
| | | if (_setting.varMark === undefined) { |
| | | _setting.varMark = this.getMark(Marks) |
| | | } |
| | | // if (_setting.varMark === undefined) { |
| | | // _setting.varMark = this.getMark(Marks) |
| | | // } |
| | | |
| | | this.setState({ |
| | | columns: fromJS(config.columns).toJS(), |
| | |
| | | handleEdit = (record) => { |
| | | this.scriptsForm.edit(record) |
| | | |
| | | let node = document.getElementById('model-verify-card-box-tab').parentNode |
| | | let node = document.getElementById('model-data-source-wrap').parentNode |
| | | |
| | | if (node && node.scrollTop) { |
| | | let inter = Math.ceil(node.scrollTop / 10) |
| | |
| | | const { columns, setting, scripts, colColumns, scriptsColumns, activeKey, loading, searches } = this.state |
| | | |
| | | return ( |
| | | <div id="model-verify-card-box-tab"> |
| | | <div id="model-data-source-wrap"> |
| | | {loading && <Spin size="large" />} |
| | | <Tabs activeKey={activeKey} className="verify-card-box" onChange={this.changeTab}> |
| | | <TabPane tab="数据源" key="setting"> |
| | |
| | | #model-verify-card-box-tab { |
| | | #model-data-source-wrap { |
| | | .ant-spin { |
| | | position: absolute; |
| | | left: calc(50% - 16px); |
| | |
| | | word-break: break-word; |
| | | } |
| | | .quickly-add { |
| | | position: relative; |
| | | position: absolute; |
| | | width: 100px; |
| | | float: right; |
| | | top: -5px; |
| | | right: 10px; |
| | | top: 5px; |
| | | z-index: 2; |
| | | } |
| | | .verify-form { |
| | |
| | | .errorval { |
| | | display: inline-block; |
| | | width: 30px; |
| | | } |
| | | .operation-btn { |
| | | display: inline-block; |
| | | font-size: 16px; |
| | | padding: 0 5px; |
| | | cursor: pointer; |
| | | } |
| | | } |
| | | } |
| | |
| | | <div className="ant-mk-slider"> |
| | | <div className="ant-mk-slider-rail"></div> |
| | | <div className="ant-mk-slider-track" style={{width: _val, backgroundColor: card.color}}></div> |
| | | <Tooltip title={val}> |
| | | <Tooltip title={`${val}%`}> |
| | | <div className="ant-mk-slider-handle" style={{left: _val, borderColor: card.color}}></div> |
| | | </Tooltip> |
| | | </div> |
| | |
| | | import { Spin, Empty, Select, notification } from 'antd' |
| | | |
| | | import asyncComponent from './asyncButtonComponent' |
| | | import { chartColors } from '@/utils/option.js' |
| | | // import searchLine from '../../share/searchLine' |
| | | import Api from '@/api' |
| | | import Utils from '@/utils/utils.js' |
| | |
| | | empty: true, // 图表数据为空 |
| | | loading: false, // 数据加载状态 |
| | | chartId: Utils.getuuid(), // 图表Id |
| | | transfield: {}, // 字段名称翻译 |
| | | title: '', // 组件标题 |
| | | sync: false, // 是否统一请求数据 |
| | | plot: null, // 图表设置 |
| | |
| | | chartData: [], // 图表数据 |
| | | chartFields: [], // 统计图表生成字段集 |
| | | selectFields: [], // 统计图表选择字段 |
| | | percentFields: [], // 设置为百分比的字段,tooltip时增加% |
| | | showHeader: false // 存在标题、搜索、或统计数据时显示 |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | let vFields = [] |
| | | let percentFields = [] |
| | | let vstFields = null |
| | | |
| | | if (_config.plot.datatype === 'statistics') { |
| | |
| | | show: _config.plot.show, |
| | | decimal |
| | | }) |
| | | |
| | | if (_config.plot.show === 'percent') { |
| | | percentFields.push(col.label) |
| | | } |
| | | } |
| | | }) |
| | | } |
| | |
| | | _config.style = {minHeight: (config.plot.height || 400)} |
| | | } |
| | | |
| | | let transfield = {} |
| | | _config.columns.forEach(col => { |
| | | if (col.field) { |
| | | transfield[col.field] = col.label |
| | | } |
| | | }) |
| | | |
| | | _config.plot.color = _config.plot.color || 'rgba(0, 0, 0, 0.85)' |
| | | |
| | | if (_config.plot.enabled === 'true' && _config.plot.customs && _config.plot.customs.length > 0) { |
| | | let colors = new Map() |
| | | let colorIndex = 0 |
| | | let limit = chartColors.length |
| | | |
| | | if (_config.plot.colors && _config.plot.colors.length > 0) { |
| | | _config.plot.colors.forEach(item => { |
| | | if (!colors.has(item.type)) { |
| | | colors.set(item.type, item.color) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | let axisIndex = 0 |
| | | let hasBar = false |
| | | let fields = [] |
| | | let legends = [] |
| | | |
| | | _config.plot.customs.forEach(item => { |
| | | item.name = transfield[item.type] || item.type |
| | | item.chartType = item.shape ? (item.shape[0] || 'bar') : 'bar' |
| | | item.shape = item.shape ? (item.shape[1] || '') : '' |
| | | |
| | | if (colors.get(item.type)) { |
| | | item.color = colors.get(item.type) |
| | | } else { |
| | | item.color = chartColors[colorIndex % limit] |
| | | colorIndex++ |
| | | } |
| | | |
| | | if (item.chartType === 'bar' && !hasBar) { |
| | | hasBar = true |
| | | } else if (item.chartType === 'bar') { |
| | | item.chartType = 'line' |
| | | item.shape = 'smooth' |
| | | } |
| | | |
| | | if (item.axis === 'true' && axisIndex < 2) { |
| | | if (axisIndex === 0) { |
| | | item.axis = { grid: {style: { fill: _config.plot.color }}, title: { style: { fill: _config.plot.color } }, label: {style: { fill: _config.plot.color }} } |
| | | fields.unshift(item) |
| | | } else { |
| | | item.axis = { grid: null, title: {style: { fill: _config.plot.color }}, label: {style: { fill: _config.plot.color }} } |
| | | fields.splice(1, 0, item) |
| | | } |
| | | axisIndex++ |
| | | } else { |
| | | item.axis = { grid: null, title: null, label: null } |
| | | 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 } } |
| | | }) |
| | | }) |
| | | _config.plot.customs = fields |
| | | _config.plot.legends = legends |
| | | _config.plot.hasBar = hasBar |
| | | } else { |
| | | _config.plot.enabled = 'false' |
| | | } |
| | | |
| | | this.setState({ |
| | | config: _config, |
| | | data: _data, |
| | | vFields: vFields, |
| | | vstFields: vstFields, |
| | | percentFields: percentFields, |
| | | arr_field: _config.columns.map(col => col.field).join(','), |
| | | plot: _config.plot, |
| | | sync: _sync, |
| | | title: config.plot.title, |
| | | search: Utils.initMainSearch(config.search), |
| | | transfield, |
| | | showHeader |
| | | }, () => { |
| | | if (config.setting.sync !== 'true' && config.setting.onload === 'true') { |
| | |
| | | this.handleData() |
| | | } |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 校验图表的按钮组,如果为统计图表,计算图表字段 |
| | | */ |
| | | componentDidMount () { |
| | | |
| | | } |
| | | |
| | | /** |
| | |
| | | * @description 折线图渲染 |
| | | */ |
| | | linerender = () => { |
| | | const { plot, config, percentFields } = this.state |
| | | const { plot, transfield } = this.state |
| | | |
| | | let _data = [] |
| | | let _valfield = 'value' |
| | | let _typefield = 'key' |
| | | let ispercent = false |
| | | |
| | | let colors = new Map() |
| | | let colorIndex = 0 |
| | | |
| | | if (plot.datatype === 'statistics') { |
| | | _valfield = plot.InfoValue |
| | | _typefield = plot.InfoType |
| | | |
| | | if (plot.show === 'percent') { |
| | | ispercent = true |
| | | if (plot.colors && plot.colors.length > 0) { // 颜色设置 |
| | | plot.colors.forEach(item => { |
| | | if (!colors.has(item.type)) { |
| | | colors.set(item.type, item.color) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | _data = this.getStaticData() |
| | | } else { |
| | | let transfield = {} |
| | | config.columns.forEach(col => { |
| | | if (col.field) { |
| | | transfield[col.field] = col.label |
| | | } |
| | | }) |
| | | |
| | | let data = this.getdata() |
| | | |
| | | if (plot.enabled === 'true') { |
| | | this.customrender(data, transfield) |
| | | this.customrender(data) |
| | | return |
| | | } |
| | | |
| | | if (plot.colors && plot.colors.length > 0) { // 颜色设置 |
| | | plot.colors.forEach(item => { |
| | | if (!colors.has(transfield[item.type])) { |
| | | colors.set(transfield[item.type], item.color) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | const ds = new DataSet() |
| | |
| | | nice: true, |
| | | range: [0, 0.93] |
| | | }) |
| | | |
| | | |
| | | // 坐标轴格式化 |
| | | chart.axis(plot.Xaxis, { |
| | | label: { |
| | |
| | | let _val = `${val}` |
| | | if (_val.length <= 11) return val |
| | | return _val.substring(0, 8) + '...' |
| | | } |
| | | } |
| | | }, |
| | | style: { fill: plot.color } |
| | | }, |
| | | line: { style: { fill: plot.color } } |
| | | }) |
| | | chart.axis(_valfield, { grid: { style: { fill: plot.color } }, label: { style: { fill: plot.color } } }) |
| | | |
| | | if (!plot.legend || plot.legend === 'hidden') { |
| | | chart.legend(false) |
| | | } else { |
| | | chart.legend({ |
| | | position: plot.legend |
| | | position: plot.legend, |
| | | itemName: { style: { fill: plot.color } } |
| | | }) |
| | | } |
| | | |
| | |
| | | let _chart = chart |
| | | .line() |
| | | .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 |
| | | value: plot.show === 'percent' ? value + '%' : value |
| | | } |
| | | }) |
| | | |
| | | if (plot.colors && plot.colors.length > 0) { |
| | | let limit = chartColors.length |
| | | _chart.color(_typefield, (key) => { |
| | | if (colors.get(key)) { |
| | | return colors.get(key) |
| | | } else { |
| | | colors.set(key, chartColors[colorIndex % limit]) |
| | | colorIndex++ |
| | | } |
| | | }) |
| | | } else { |
| | | _chart.color(_typefield) |
| | | } |
| | | if (plot.label === 'true') { |
| | | _chart.label(_valfield) |
| | | _chart.label(_valfield, (value) => { |
| | | if (plot.show === 'percent') { |
| | | value = value + '%' |
| | | } |
| | | return { |
| | | content: value, |
| | | style: { |
| | | fill: plot.color |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | if (plot.point === 'true') { |
| | | if (plot.point === 'true' && plot.colors && plot.colors.length > 0) { |
| | | let limit = chartColors.length |
| | | chart |
| | | .point() |
| | | .position(`${plot.Xaxis}*${_valfield}`) |
| | | .color(_typefield, (key) => { |
| | | if (colors.get(key)) { |
| | | return colors.get(key) |
| | | } else { |
| | | colors.set(key, chartColors[colorIndex % limit]) |
| | | colorIndex++ |
| | | } |
| | | }) |
| | | .size(3) |
| | | .shape('circle') |
| | | } else if (plot.point === 'true') { |
| | | chart |
| | | .point() |
| | | .position(`${plot.Xaxis}*${_valfield}`) |
| | |
| | | /** |
| | | * @description 自定义渲染 |
| | | */ |
| | | customrender = (data, transfield) => { |
| | | const { plot, percentFields } = this.state |
| | | |
| | | let barfields = [] |
| | | let fields = [] |
| | | let legends = [] |
| | | |
| | | 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) |
| | | |
| | | customrender = (data) => { |
| | | const { plot } = this.state |
| | | 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] |
| | | plot.customs.forEach(line => { |
| | | row[line.name] = row[line.type] |
| | | }) |
| | | return row |
| | | } |
| | |
| | | height: plot.height || 400 |
| | | }) |
| | | |
| | | chart.data(dv.rows) |
| | | let _data = dv.rows |
| | | // 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] += ' ' |
| | | } |
| | | |
| | | if (plot.coordinate !== 'polar' && barfields.length === 0) { |
| | | chart.data(_data) |
| | | |
| | | if (!plot.hasBar) { |
| | | chart.scale(plot.Xaxis, { |
| | | range: [0, 1] |
| | | }) |
| | | } else { |
| | | chart.scale(plot.Xaxis, { |
| | | range: [0.05, 0.95] |
| | | }) |
| | | } |
| | | |
| | |
| | | let _val = `${val}` |
| | | if (_val.length <= 11) return val |
| | | return _val.substring(0, 8) + '...' |
| | | } |
| | | } |
| | | }, |
| | | style: { fill: plot.color } |
| | | }, |
| | | line: { style: { fill: plot.color } } |
| | | }) |
| | | |
| | | if (!plot.legend || plot.legend === 'hidden') { |
| | |
| | | chart.legend({ |
| | | custom: true, |
| | | position: plot.legend, |
| | | items: legends, |
| | | items: plot.legends, |
| | | itemName: { style: { fill: plot.color } } |
| | | }) |
| | | } |
| | | |
| | |
| | | }) |
| | | } |
| | | |
| | | if (plot.transpose === 'true') { |
| | | chart.coordinate().transpose() |
| | | } |
| | | |
| | | if (plot.coordinate === 'polar') { |
| | | chart.coordinate('polar', { |
| | | innerRadius: 0.1, |
| | | radius: 0.8 |
| | | plot.customs.forEach((item, i) => { |
| | | chart.axis(item.name, item.axis) |
| | | |
| | | chart.scale(item.name, { |
| | | nice: true, |
| | | range: [0, 0.93] |
| | | }) |
| | | } |
| | | |
| | | 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 |
| | |
| | | .tooltip(`${item.name}`, (value) => { |
| | | return { |
| | | name: item.name, |
| | | value: percentFields.includes(item.name) ? value + '%' : value |
| | | value: plot.show === 'percent' ? value + '%' : value |
| | | } |
| | | }) |
| | | |
| | | if (plot.barSize) { |
| | | _chart.size(plot.barSize || 35) |
| | | } |
| | | if (item.label === 'true') { |
| | | _chart.label(item.name) |
| | | _chart.label(item.name, (value) => { |
| | | if (plot.show === 'percent') { |
| | | value = value + '%' |
| | | } |
| | | return { |
| | | content: value, |
| | | style: { |
| | | fill: plot.color |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | } else if (item.chartType === 'line') { |
| | | let _chart = chart |
| | |
| | | .tooltip(`${item.name}`, (value) => { |
| | | return { |
| | | name: item.name, |
| | | value: percentFields.includes(item.name) ? value + '%' : value |
| | | value: plot.show === 'percent' ? value + '%' : value |
| | | } |
| | | }) |
| | | |
| | | if (item.label === 'true') { |
| | | _chart.label(item.name) |
| | | _chart.label(item.name, (value) => { |
| | | if (plot.show === 'percent') { |
| | | value = value + '%' |
| | | } |
| | | return { |
| | | content: value, |
| | | style: { |
| | | fill: plot.color |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | if (plot.point === 'true') { |
| | |
| | | * @description 柱状图渲染 |
| | | */ |
| | | barrender = () => { |
| | | const { plot, config, percentFields } = this.state |
| | | const { plot, transfield } = this.state |
| | | |
| | | let _data = [] |
| | | let _valfield = 'value' |
| | | let _typefield = 'key' |
| | | let ispercent = false |
| | | |
| | | let colors = new Map() |
| | | let colorIndex = 0 |
| | | |
| | | if (plot.datatype === 'statistics') { |
| | | _valfield = plot.InfoValue |
| | | _typefield = plot.InfoType |
| | | |
| | | if (plot.show === 'percent') { |
| | | ispercent = true |
| | | if (plot.colors && plot.colors.length > 0) { // 颜色设置 |
| | | plot.colors.forEach(item => { |
| | | if (!colors.has(item.type)) { |
| | | colors.set(item.type, item.color) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | _data = this.getStaticData() |
| | | } else { |
| | | let transfield = {} |
| | | config.columns.forEach(col => { |
| | | if (col.field) { |
| | | transfield[col.field] = col.label |
| | | } |
| | | }) |
| | | |
| | | let data = this.getdata() |
| | | |
| | | if (plot.enabled === 'true') { |
| | | this.customrender(data, transfield) |
| | | this.customrender(data) |
| | | return |
| | | } |
| | | |
| | | if (plot.colors && plot.colors.length > 0) { // 颜色设置 |
| | | plot.colors.forEach(item => { |
| | | if (!colors.has(transfield[item.type])) { |
| | | colors.set(transfield[item.type], item.color) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | const ds = new DataSet() |
| | |
| | | let _val = `${val}` |
| | | if (_val.length <= 11) return val |
| | | return _val.substring(0, 8) + '...' |
| | | } |
| | | } |
| | | }, |
| | | style: { fill: plot.color } |
| | | }, |
| | | line: { style: { fill: plot.color } } |
| | | }) |
| | | chart.axis(_valfield, { grid: { style: { fill: plot.color } }, label: { style: { fill: plot.color } } }) |
| | | |
| | | if (!plot.legend || plot.legend === 'hidden') { |
| | | chart.legend(false) |
| | | } else { |
| | | chart.legend({ |
| | | position: plot.legend |
| | | position: plot.legend, |
| | | itemName: { style: { fill: plot.color } } |
| | | }) |
| | | } |
| | | |
| | |
| | | let _chart = chart |
| | | .interval() |
| | | .position(`${plot.Xaxis}*${_valfield}`) |
| | | .color(_typefield) |
| | | .adjust([ |
| | | { |
| | | type: 'dodge', |
| | |
| | | .tooltip(`${plot.Xaxis}*${_valfield}*${_typefield}`, (name, value, type) => { |
| | | return { |
| | | name: type, |
| | | value: percentFields.includes(type) || ispercent ? value + '%' : value |
| | | value: plot.show === 'percent' ? value + '%' : value |
| | | } |
| | | }) |
| | | |
| | | if (plot.colors && plot.colors.length > 0) { |
| | | let limit = chartColors.length |
| | | _chart.color(_typefield, (key) => { |
| | | if (colors.get(key)) { |
| | | return colors.get(key) |
| | | } else { |
| | | colors.set(key, chartColors[colorIndex % limit]) |
| | | colorIndex++ |
| | | } |
| | | }) |
| | | } else { |
| | | _chart.color(_typefield) |
| | | } |
| | | if (plot.label === 'true') { |
| | | _chart.label(_valfield) |
| | | _chart.label(_valfield, (value) => { |
| | | if (plot.show === 'percent') { |
| | | value = value + '%' |
| | | } |
| | | return { |
| | | content: value, |
| | | style: { |
| | | fill: plot.color |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | if (plot.barSize || plot.correction) { |
| | |
| | | let _chart = chart |
| | | .interval() |
| | | .position(`${plot.Xaxis}*${_valfield}`) |
| | | .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 |
| | | value: plot.show === 'percent' ? value + '%' : value |
| | | } |
| | | }) |
| | | |
| | | if (plot.colors && plot.colors.length > 0) { |
| | | let limit = chartColors.length |
| | | _chart.color(_typefield, (key) => { |
| | | if (colors.get(key)) { |
| | | return colors.get(key) |
| | | } else { |
| | | colors.set(key, chartColors[colorIndex % limit]) |
| | | colorIndex++ |
| | | } |
| | | }) |
| | | } else { |
| | | _chart.color(_typefield) |
| | | } |
| | | if (plot.label === 'true') { |
| | | _chart.label(_valfield) |
| | | _chart.label(_valfield, (value) => { |
| | | if (plot.show === 'percent') { |
| | | value = value + '%' |
| | | } |
| | | return { |
| | | content: value, |
| | | style: { |
| | | fill: plot.color |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | if (plot.barSize || plot.correction) { |
| | |
| | | // import searchLine from '../../share/searchLine' |
| | | import Api from '@/api' |
| | | import Utils from '@/utils/utils.js' |
| | | import { chartColors } from '@/utils/option.js' |
| | | import UtilsDM from '@/utils/utils-datamanage.js' |
| | | import './index.scss' |
| | | |
| | |
| | | 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])) { |
| | |
| | | |
| | | Y_axis = 'percent' // 显示百分比 |
| | | } |
| | | |
| | | chart.data(dv.rows) |
| | | |
| | | if (plot.shape === 'nightingale') { |
| | |
| | | }) |
| | | } |
| | | |
| | | let colors = new Map() |
| | | let colorIndex = 0 |
| | | |
| | | if (plot.colors && plot.colors.length > 0) { |
| | | plot.colors.forEach(item => { |
| | | if (!colors.has(item.label)) { |
| | | colors.set(item.label, item.color) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | if (plot.shape !== 'nightingale') { |
| | | let _chart = chart |
| | | .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) + '%' |
| | |
| | | value: value |
| | | } |
| | | }) |
| | | if (plot.colors && plot.colors.length > 0) { |
| | | let limit = chartColors.length |
| | | _chart.color(X_axis, (type) => { |
| | | if (colors.get(type)) { |
| | | return colors.get(type) |
| | | } else { |
| | | colors.set(type, chartColors[colorIndex % limit]) |
| | | colorIndex++ |
| | | } |
| | | }) |
| | | } else { |
| | | _chart.color(X_axis) |
| | | } |
| | | if (plot.label !== 'false') { |
| | | if (plot.label === 'inner') { |
| | | _chart.label(Y_axis, { |
| | |
| | | let _chart = chart |
| | | .interval() |
| | | .position(`${X_axis}*${Y_axis}`) |
| | | .color(X_axis) |
| | | |
| | | if (plot.label !== 'false') { |
| | | let _label = {} |
| | | if (plot.label === 'inner') { |
| | | _label.offset = -15 |
| | | if (plot.colors && plot.colors.length > 0) { |
| | | let limit = chartColors.length |
| | | _chart.color(X_axis, (type) => { |
| | | if (colors.get(type)) { |
| | | return colors.get(type) |
| | | } else { |
| | | _label.style = { |
| | | fill: color |
| | | } |
| | | colors.set(type, chartColors[colorIndex % limit]) |
| | | colorIndex++ |
| | | } |
| | | |
| | | _chart.label(X_axis, _label) |
| | | .style({ |
| | | lineWidth: 1, |
| | | stroke: '#fff', |
| | | }) |
| | | }) |
| | | } else { |
| | | _chart.color(X_axis) |
| | | } |
| | | if (plot.label !== 'false') { |
| | | let _label = {} |
| | | if (plot.label === 'inner') { |
| | | _label.offset = -15 |
| | | } else { |
| | | _label.style = { |
| | | fill: color |
| | | } |
| | | } |
| | | |
| | | _chart.label(X_axis, _label) |
| | | .style({ |
| | | lineWidth: 1, |
| | | stroke: '#fff', |
| | | }) |
| | | } |
| | | } |
| | | |
| | | chart.render() |
| | |
| | | } |
| | | |
| | | componentDidMount () { |
| | | this.loadHomeConfig() |
| | | } |
| | | |
| | | loadHomeConfig = () => { |
| | | let _param = { |
| | | func: 'sPC_Get_LongParam', |
| | | MenuID: this.props.MenuID |
| | |
| | | Api.genericInterface(param).then(res => { |
| | | resolve() |
| | | if (res.status) { |
| | | sessionStorage.setItem('avatar', res.icon || '') |
| | | sessionStorage.setItem('UserID', res.UserID) |
| | | sessionStorage.setItem('LoginUID', res.LoginUID) |
| | | sessionStorage.setItem('User_Name', res.UserName) |
| | | sessionStorage.setItem('Full_Name', res.FullName) |
| | | sessionStorage.setItem('avatar', res.icon || '') |
| | | sessionStorage.setItem('dataM', res.dataM ? 'true' : '') |
| | | sessionStorage.setItem('debug', res.debug || '') |
| | | sessionStorage.setItem('role_id', res.role_id || '') |
| | | |
| | | sessionStorage.removeItem('CloudAvatar') |
| | | sessionStorage.removeItem('cloudDataM') |
| | | sessionStorage.removeItem('CloudUserID') |
| | | sessionStorage.removeItem('CloudUserName') |
| | | sessionStorage.removeItem('CloudLoginUID') |
| | | sessionStorage.removeItem('CloudFullName') |
| | | |
| | | window.location.reload() |
| | | } else { |
| | |
| | | import React, { Component } from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Table, Input, InputNumber, Popconfirm, Form, Icon, Select } from 'antd' |
| | | import { Table, Input, InputNumber, Popconfirm, Form, Icon, Select, Radio, Cascader } from 'antd' |
| | | |
| | | import ColorSketch from '@/mob/colorsketch' |
| | | // 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' |
| | | |
| | | let eTDict = localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS |
| | | const EditableContext = React.createContext() |
| | | |
| | | class EditableCell extends Component { |
| | |
| | | } else if (inputType === 'color') { |
| | | return <ColorSketch /> |
| | | } else if (inputType === 'select') { |
| | | return <Select> |
| | | {options.map((item, i) => (<Select.Option key={i} value={item.field || item.value}> {item.label || item.text} </Select.Option>))} |
| | | </Select> |
| | | return ( |
| | | <Select> |
| | | {options.map((item, i) => (<Select.Option key={i} value={item.field || item.value}> {item.label || item.text} </Select.Option>))} |
| | | </Select> |
| | | ) |
| | | } else if (inputType === 'cascader') { |
| | | return ( |
| | | <Cascader options={options} placeholder=""/> |
| | | ) |
| | | } else if (inputType === 'radio') { |
| | | return ( |
| | | <Radio.Group> |
| | | {options.map((item, i) => (<Radio key={i} value={item.field || item.value}> {item.label || item.text} </Radio>))} |
| | | </Radio.Group> |
| | | ) |
| | | } else { |
| | | return <Input onPressEnter={() => this.getValue(form)} /> |
| | | } |
| | |
| | | |
| | | renderCell = (form) => { |
| | | const { getFieldDecorator } = form |
| | | const { editing, dataIndex, title, record, children, className, required } = this.props |
| | | const { editing, dataIndex, title, record, children, className, required, inputType } = this.props |
| | | |
| | | return ( |
| | | <td className={className}> |
| | |
| | | rules: [ |
| | | { |
| | | required: required, |
| | | message: `Please Input ${title}!`, |
| | | message: ['number', 'text', 'input'].includes(inputType) ? `${eTDict['form.required.input']} ${title}!` : `${eTDict['form.required.select']} ${title}!`, |
| | | } |
| | | ], |
| | | initialValue: record[dataIndex], |
| | |
| | | |
| | | class EditTable extends Component { |
| | | static propTpyes = { |
| | | actions: PropTypes.any, // 操作项 |
| | | data: PropTypes.any, // 数据列表 |
| | | columns: PropTypes.array, // 显示列 |
| | | onChange: PropTypes.func // 数据变化 |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { data } = this.props |
| | | const { data, actions } = this.props |
| | | let columns = fromJS(this.props.columns).toJS() |
| | | let dict = localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS |
| | | |
| | | columns.push({ |
| | | title: dict['model.operation'], |
| | | title: eTDict['model.operation'], |
| | | dataIndex: 'operation', |
| | | width: '140px', |
| | | render: (text, record) => { |
| | | const { editingKey } = this.state |
| | | const editable = this.isEditing(record) |
| | | return editable ? ( |
| | | <span> |
| | | <span style={{textAlign: 'center', display: 'block'}}> |
| | | <EditableContext.Consumer> |
| | | {form => ( |
| | | <span onClick={() => this.save(form, record.uuid)} style={{ marginRight: 8 , color: '#1890ff', cursor: 'pointer'}}> |
| | | {dict['model.save']} |
| | | {eTDict['model.save']} |
| | | </span> |
| | | )} |
| | | </EditableContext.Consumer> |
| | | <span style={{ color: '#1890ff', cursor: 'pointer'}} onClick={() => this.cancel(record.uuid)}>{dict['model.cancel']}</span> |
| | | <span style={{ color: '#1890ff', cursor: 'pointer'}} onClick={() => this.cancel(record.uuid)}>{eTDict['model.cancel']}</span> |
| | | </span> |
| | | ) : ( |
| | | <div className={'operation-btn' + (editingKey !== '' ? ' disabled' : '')}> |
| | | <span className="primary" onClick={() => {editingKey === '' && this.edit(record.uuid)}}><Icon type="edit" /></span> |
| | | <span className="primary" onClick={() => {editingKey === '' && this.handleUpDown(record.uuid, 'up')}}><Icon type="arrow-up" /></span> |
| | | <span className="danger" onClick={() => {editingKey === '' && this.handleUpDown(record.uuid, 'down')}}><Icon type="arrow-down" /></span> |
| | | {editingKey === '' ? <Popconfirm |
| | | {!actions || actions.includes('edit') ? <span className="primary" onClick={() => {editingKey === '' && this.edit(record.uuid)}}><Icon type="edit" /></span> : null} |
| | | {!actions || actions.includes('up') ? <span className="primary" onClick={() => {editingKey === '' && this.handleUpDown(record.uuid, 'up')}}><Icon type="arrow-up" /></span> : null} |
| | | {!actions || actions.includes('down') ? <span className="danger" onClick={() => {editingKey === '' && this.handleUpDown(record.uuid, 'down')}}><Icon type="arrow-down" /></span> : null} |
| | | {(!actions || actions.includes('del')) && editingKey === '' ? <Popconfirm |
| | | overlayClassName="popover-confirm" |
| | | title={dict['model.query.delete']} |
| | | title={eTDict['model.query.delete']} |
| | | onConfirm={() => this.handleDelete(record.uuid) |
| | | }> |
| | | <span className="danger"><Icon type="delete" /></span> |
| | | </Popconfirm> : null} |
| | | {editingKey !== '' ? <span className="danger"><Icon type="delete" /></span> : null} |
| | | {(!actions || actions.includes('del')) && editingKey !== '' ? <span className="danger"><Icon type="delete" /></span> : null} |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | |
| | | this.setState({ |
| | | data: data || [], |
| | | columns, |
| | | dict |
| | | columns |
| | | }) |
| | | } |
| | | |
| | |
| | | padding: 16px 10px; |
| | | } |
| | | } |
| | | |
| | | thead tr th:last-child { |
| | | text-align: center; |
| | | } |
| | | .operation-btn { |
| | | display: block; |
| | | text-align: center; |
| | | span { |
| | | margin-right: 10px; |
| | | cursor: pointer; |
| | |
| | | hidden: true |
| | | }, |
| | | { |
| | | title: '新页面', |
| | | title: '外部页面', |
| | | type: 'NewPage', |
| | | url: customImg, |
| | | baseconfig: '', |
| | |
| | | } |
| | | ] |
| | | |
| | | // 图表色系 |
| | | export const chartColors = ['rgb(91, 143, 249)', 'rgb(90, 216, 166)', 'rgb(93, 112, 146)', 'rgb(246, 189, 22)', 'rgb(232, 100, 82)', 'rgb(109, 200, 236)', 'rgb(148, 95, 185)', 'rgb(246, 189, 22)', 'rgb(205, 221, 253)', 'rgb(248, 208, 203)'] |
| | | |
| | | // 日期默认值选择范围 |
| | | export const dateOptions = { |
| | | date: [ |
| | |
| | | Api.getSystemConfig(param).then(response => { |
| | | if (response.status) { |
| | | this.setState({ |
| | | oriConfig: fromJS(config).toJS(), |
| | | oriConfig: fromJS(_config).toJS(), |
| | | openEdition: response.open_edition || '', |
| | | menuloading: false |
| | | }) |