Browse Source

图表查看列功能重新设计,与导出逻辑统一

zhuth 6 years ago
parent
commit
bea489267c

+ 9 - 2
src/components/chartDesigner/sections/aggregateTableConfigForm.jsx

@@ -56,9 +56,16 @@ class AggregateTableConfigForm extends React.Component {
 				<FormItem label='显示总体数据' {...formItemLayout}>
 					<CheckboxGroup
 						className='checkbox-group-statistics'
-						value={aggregateTableConfig.statistics}
+						value={aggregateTableConfig.statistics.map(s => s.name || s)}
 						onChange={(value) => {
-							dispatch({ type: 'chartDesigner/changeField', name: 'aggregateTableConfig', value: { ...props.chartDesigner.aggregateTableConfig, statistics: value }, autoRefresh });
+							let statistics = value.map(v => {
+								let f = STATISTICS_OPTION.find(s => s.value === v);
+								return {
+									name: f.value,
+									label: f.label
+								}
+							});
+							dispatch({ type: 'chartDesigner/changeField', name: 'aggregateTableConfig', value: { ...props.chartDesigner.aggregateTableConfig, statistics }, autoRefresh });
 						}}
 					>
 						<Row>

+ 97 - 0
src/components/chartDesigner/sections/chartDataPreview.jsx

@@ -0,0 +1,97 @@
+import React from 'react';
+import { connect } from 'dva';
+import { Modal, Table } from 'antd';
+import moment from 'moment';
+import EllipsisTooltip from '../../common/ellipsisTooltip/index';
+import './chartDataPreview.less';
+
+class ChartDataPreview extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {
+            loading: false,
+            columns: [],
+            dataSource: []
+        }
+    }
+    componentDidMount() {
+        const { dispatch, chartCode, chartType, chartOption, chartConfig, filters } = this.props;
+        let h = document.body.clientHeight * 0.8 - 40 - 40 - 40 - 2;
+        this.setState({
+            loading: true,
+            tableBodyHeight: h,
+            pageSize: Math.ceil(h / 38)
+        }, () => {
+            dispatch({ type: 'chartDesigner/getChartTableData', chartCode, chartType, chartOption, chartConfig, filters }).then(data => {
+                this.setState({
+                    loading: false,
+                    columns: data.columns,
+                    dataSource: data.dataSource
+                });
+            });
+        });
+    }
+    render() {
+        const { modalClassName, visibleBox, hideBox } = this.props;
+        const { columns, dataSource, loading, pageSize, tableBodyHeight } = this.state;
+        return <Modal
+            className={`datapreview chartdatapreview ${modalClassName}`}
+            title='查看列'
+            width={800}
+            visible={visibleBox}
+            footer={null}
+            onCancel={() => {
+                hideBox()
+            }}
+            maskClosable={true}
+        >
+            <Table
+                columns={columns.map((c, i) => {
+                    let obj = {
+                        ...c,
+                        onCell: () => {
+                            return {
+                                style: {
+                                    whiteSpace: 'nowrap',
+                                    maxWidth: 150,
+                                }
+                            }
+                        },
+                    };
+                    if(c.type === 'time') {
+                        obj.render = v => {
+                            let text = v === null ? '空' : (moment(v).isValid() ? moment(v).format('YYYY-MM-DD') : v)
+                            return <EllipsisTooltip key={i} title={text}>{text}</EllipsisTooltip>
+                        }
+                    }else {
+                        obj.render = v => {
+                            let text = v === null ? '空' : v
+                            return <EllipsisTooltip key={i} title={text}>{text}</EllipsisTooltip>
+                        }
+                    }
+                    if(i !== columns.length - 1) {
+                        obj.width = 150
+                    }
+                    return obj; 
+                })}
+                dataSource={dataSource.map((d, i) => ({
+                    ...d,
+                    key: i
+                }))}
+                loading={loading}
+                size='small'
+                pagination={{
+                    pageSize,
+                    total: dataSource.length,
+                    // simple: true,
+                    showTotal: (total, range) => {
+                        return `第${range[0]}到第${range[1]}条数据,共${total}条数据`;
+                    }
+                }}
+                scroll={{ x: columns ? columns.length * 150 : false, y: tableBodyHeight }}
+            />
+        </Modal>
+    }
+}
+
+export default connect()(ChartDataPreview);

+ 3 - 0
src/components/chartDesigner/sections/chartDataPreview.less

@@ -0,0 +1,3 @@
+.ant-modal.chartdatapreview {
+    top: 50px;
+}

+ 26 - 25
src/components/chartDesigner/sections/toolbar.jsx

@@ -1,12 +1,13 @@
-import React from 'react'
-import { Tag, Icon } from 'antd'
-import FilterBox from '../../common/filterBox/filterBox'
-import { connect } from 'dva'
-import moment from 'moment'
-import DataPreview from '../../common/dataPreview/dataPreview'
-import Filter from '../../common/filterBox/filter'
-// import CusIcon from '../../common/cusIcon/index'
-import './toolbar.less'
+import React from 'react';
+import { Tag, Icon, message } from 'antd';
+import FilterBox from '../../common/filterBox/filterBox';
+import { connect } from 'dva';
+import moment from 'moment';
+import Filter from '../../common/filterBox/filter';
+import CusIcon from '../../common/cusIcon/index';
+import ChartDataPreview from './chartDataPreview';
+import { isEqual } from '../../../utils/baseUtils.js';
+import './toolbar.less';
 
 class Toolbar extends React.Component {
     constructor(props) {
@@ -103,8 +104,10 @@ class Toolbar extends React.Component {
     }
 
     render() {
-        const { chartDesigner, dispatch, isOwner } = this.props;
-        const { code, filters, columns } = chartDesigner;
+        const { chartDesigner, isOwner } = this.props;
+        const { code, filters, columns, baseConfig, chartOption } = chartDesigner;
+        const { viewType } = baseConfig
+        const chartConfig = chartDesigner[`${viewType}Config`]
         const { visibleFilterBox, visibleDataPreviewBox } = this.state;
 
         return (
@@ -125,34 +128,32 @@ class Toolbar extends React.Component {
                         />
                     ))}
                 </div>
-                {/* <div className='tools'>
+                <div className='tools'>
                     <span onClick={() => {
+                        if(isEqual(chartOption, {})) {
+                            message.error('暂无数据');
+                            return;
+                        }
                         this.setState({
                             visibleDataPreviewBox: true
                         })
                     }}>
                         <CusIcon type='bi-view-columns'/>查看列
                     </span>
-                </div> */}
+                </div>
                 {visibleFilterBox && <FilterBox code={code} columns={columns} filterData={filters} visibleFilterBox={visibleFilterBox} showFilterBox={this.showFilterBox} hideFilterBox={this.hideFilterBox} createFilters={this.createFilters} />}
-                {visibleDataPreviewBox && <DataPreview
-                    title='查看列'
+                {visibleDataPreviewBox && <ChartDataPreview
                     visibleBox={visibleDataPreviewBox}
                     hideBox={() => {
                         this.setState({
                             visibleDataPreviewBox: false
                         });
                     }}
-                    fetchFunction={(page, pageSize) => {
-                        dispatch({ type: 'chartDesigner/remoteChartDataList', page, pageSize }).then(() => {
-                            // 主动触发一次window的resize事件
-                            window.setTimeout(() => {
-                                var e = document.createEvent("Event");
-                                e.initEvent("resize", true, true);
-                                window.dispatchEvent(e);
-                            }, 20);
-                        });
-                    }}
+                    chartCode={code}
+                    chartType={viewType}
+                    chartOption={chartOption}
+                    chartConfig={chartConfig}
+                    filters={filters}
                 />}
             </div>
         );

+ 238 - 146
src/models/chartDesigner.js

@@ -1,9 +1,10 @@
-import { message } from 'antd'
-import * as service from '../services/index'
-import URLS from '../constants/url'
-import parseChartOption from './parseChartOption'
-import { deepAssign } from '../utils/baseUtils'
-import moment from 'moment'
+import { message } from 'antd';
+import * as service from '../services/index';
+import URLS from '../constants/url';
+import parseChartOption from './parseChartOption';
+import { deepAssign } from '../utils/baseUtils';
+import STATISTICS_OPTION from '../components/chartDesigner/sections/statisticsOption.json';
+import moment from 'moment';
 
 function getBodyFilters(filters) {
     let bodyFilters = [];
@@ -697,12 +698,23 @@ export default {
             try {
                 const chartDesigner = yield select(state => state.present.chartDesigner);
                 const { code, aggregateTableConfig, filters, theme, styleConfig } = chartDesigner;
-                const { targetColumn, statistics } = aggregateTableConfig;
+                const { targetColumn, statistics: statisticsNames } = aggregateTableConfig;
+
+                let statistics = statisticsNames.map(s => {
+                    if(!s.name) {
+                        let f = STATISTICS_OPTION.find(o => o.value === s);
+                        return !!f ? {
+                            name: f.value,
+                            label: f.label
+                        } : null;
+                    }
+                    return s
+                }).filter(s => !!s);
 
                 const body = {
                     id: code,
                     columnName: targetColumn.name,
-                    operatorList: statistics,
+                    operatorList: statistics.map(s => s.name || s),
                     groupByList: aggregateTableConfig.groupBy && aggregateTableConfig.groupBy.length > 0 ? aggregateTableConfig.groupBy.map(g => g.key) : [],
                     filters: getBodyFilters(filters),
                     testPage: {
@@ -788,155 +800,235 @@ export default {
                 message.error('请求指标数据失败: ' + e.message);
             }
         },
-        /**
-         * 将图表数据以表格的方式作为预览
-         */
-        *remoteChartDataList(action, { select, call, put }) {
+        *getChartTableData(action, { select, call, put }) {
             try {
-                const chartDesigner = yield select(state => state.present.chartDesigner);
-                const { code, baseConfig, aggregateTableConfig, lineConfig, barConfig, pieConfig, scatterConfig, dataViewConfig, filters } = chartDesigner;
-                const { viewType } = baseConfig;
-                const { page, pageSize } = action;
-
+                const { chartCode, chartType, chartOption, filters } = action;
                 let columns = [];
-                let columnListName = [];
-                let sortColumn = null;
-
-                if(viewType === 'aggregateTable') {
-                    const { groupBy, targetColumn } = aggregateTableConfig;
-                    groupBy.map(g => ({
-                        label: g.label,
-                        name: g.key,
-                    })).concat([targetColumn]).filter(x => !!x.name).forEach(x => {
-                        if(!columns.find(c => c.name === x.name)) {
-                            columns.push(x);
-                        }
-                    });;
-                    sortColumn = targetColumn.name;
-                }else if(viewType === 'line') {
-                    const { groupBy, xAxis, yAxis } = lineConfig;
-                    [{
-                        label: groupBy ? groupBy.label : '',
-                        name: groupBy ? groupBy.key : '',
-                        type: groupBy ? groupBy.type : '',
-                    }, {
-                        label: xAxis.column.label,
-                        name: xAxis.column.value,
-                        type: xAxis.column.type,
-                    }, {
-                        label: yAxis.column.label,
-                        name: yAxis.column.value,
-                        type: yAxis.column.type,
-                    }].filter(x => !!x.name).forEach(x => {
-                        if(!columns.find(c => c.name === x.name)) {
-                            columns.push(x);
+                let dataSource = [];
+                switch(chartType) {
+                    case 'bar':
+                    case 'line': {
+                        const { baseOption } = chartOption;
+                        const { originConfig, xAxis, series } = baseOption;
+                        const { xAxis: oxAxis, yAxis: oyAxis, groupBy: ogroupBy } = originConfig;
+                        columns = [{
+                            title: `${oxAxis.column.label}${oxAxis.granularity.value ? `(${oxAxis.granularity.label})` : ''}`,
+                            dataIndex: 'xAxis',
+                            type: 'string'
+                        }, {
+                            title: `${oyAxis.column.label}${oyAxis.gauge.value ? `(${oyAxis.gauge.label})` : ''}`,
+                            dataIndex: 'yAxis',
+                            type: 'scale'
+                        }];
+                        if(ogroupBy && ogroupBy.key) {
+                            columns.push({
+                                title: ogroupBy.label,
+                                dataIndex: 'groupBy',
+                                type: 'string'
+                            });
                         }
-                    });;
-                    sortColumn = xAxis.column.value;
-                }else if(viewType === 'bar') {
-                    const { groupBy, xAxis, yAxis } = barConfig;
-                    [{
-                        label: groupBy ? groupBy.label : '',
-                        name: groupBy ? groupBy.key : '',
-                        type: groupBy ? groupBy.type : '',
-                    }, {
-                        label: xAxis.column.label,
-                        name: xAxis.column.value,
-                        type: xAxis.column.type,
-                    }, {
-                        label: yAxis.column.label,
-                        name: yAxis.column.value,
-                        type: yAxis.column.type,
-                    }].filter(x => !!x.name).forEach(x => {
-                        if(!columns.find(c => c.name === x.name)) {
-                            columns.push(x);
-                        }
-                    });;
-                    sortColumn = xAxis.column.value;
-                }else if(viewType === 'pie') {
-                    const { xAxis, yAxis } = pieConfig;
-                    [{
-                        label: xAxis.column.label,
-                        name: xAxis.column.value,
-                        type: xAxis.column.type,
-                    }, {
-                        label: yAxis.column.label,
-                        name: yAxis.column.value,
-                        type: yAxis.column.type,
-                    }].filter(x => !!x.name).forEach(x => {
-                        if(!columns.find(c => c.name === x.name)) {
-                            columns.push(x);
+                        xAxis[0].data.forEach((d, i) => {
+                            if(ogroupBy && ogroupBy.key) {
+                                series.forEach(xs => {
+                                    dataSource.push({
+                                        xAxis: d,
+                                        yAxis: xs.data[i],
+                                        groupBy: xs.name
+                                    });
+                                })
+                            }else {
+                                dataSource.push({
+                                    xAxis: d,
+                                    yAxis: series[0].data[i]
+                                })
+                            }
+                        })
+                        break;
+                    }
+                    case 'pie': {
+                        const { baseOption } = chartOption;
+                        const { originConfig, series } = baseOption;
+                        const { xAxis: oxAxis, yAxis: oyAxis } = originConfig;
+                        columns = [{
+                            title: `${oxAxis.column.label}${oxAxis.granularity.value ? `(${oxAxis.granularity.label})` : ''}`,
+                            dataIndex: 'xAxis',
+                            type: 'string'
+                        }, {
+                            title: `${oyAxis.column.label}${oyAxis.gauge.value ? `(${oyAxis.gauge.label})` : ''}`,
+                            dataIndex: 'yAxis',
+                            type: 'scale'
+                        }];
+                        dataSource = series[0].data.map(d => ({
+                            xAxis: d.name,
+                            yAxis: d.value
+                        }))
+                        break;
+                    }
+                    case 'scatter': {
+                        const { baseOption } = chartOption;
+                        const { originConfig, series } = baseOption;
+                        const { xAxis: oxAxis, yAxis: oyAxis, groupBy: ogroupBy } = originConfig;
+                        columns = [{
+                            title: oxAxis.column.label,
+                            dataIndex: 'xAxis',
+                            type: 'scale'
+                        }, {
+                            title: `${oyAxis.column.label}${oyAxis.gauge.value ? `(${oyAxis.gauge.label})` : ''}`,
+                            dataIndex: 'yAxis',
+                            type: 'scale'
+                        }];
+                        if(ogroupBy && ogroupBy.key) {
+                            columns.push({
+                                title: ogroupBy.label,
+                                dataIndex: 'groupBy',
+                                type: 'string'
+                            });
                         }
-                    });;
-                    sortColumn = xAxis.column.value;
-                }else if(viewType === 'scatter') {
-                    const { groupBy, xAxis, yAxis } = scatterConfig;
-                    [{
-                        label: groupBy ? groupBy.label : '',
-                        name: groupBy ? groupBy.key : '',
-                        type: groupBy ? groupBy.type : '',
-                    }, {
-                        label: xAxis.column.label,
-                        name: xAxis.column.value,
-                        type: xAxis.column.type,
-                    }, {
-                        label: yAxis.column.label,
-                        name: yAxis.column.value,
-                        type: yAxis.column.type,
-                    }].filter(x => !!x.name).forEach(x => {
-                        if(!columns.find(c => c.name === x.name)) {
-                            columns.push(x);
+                        series.forEach(xs => {
+                            xs.data.forEach(xd => {
+                                if(ogroupBy && ogroupBy.key) {
+                                    dataSource.push({
+                                        xAxis: xd[0],
+                                        yAxis: xd[1],
+                                        groupBy: xs.name
+                                    });
+                                }else {
+                                    dataSource.push({
+                                        xAxis: xd[0],
+                                        yAxis: xd[1]
+                                    });
+                                }
+                            });
+                        })
+                        break;
+                    }
+                    case 'dataView': {
+                        const { originConfig } = chartOption;
+                        const { viewColumns } = originConfig;
+                        columns = viewColumns.map(c => ({
+                            title: c.label,
+                            dataIndex: c.name,
+                            type: 'string'
+                        }));
+                        const body = {
+                            id: chartCode,
+                            columnListName: viewColumns.map(c => c.name),
+                            sortColumn: originConfig.sortColumn ? originConfig.sortColumn.key : originConfig.viewColumns[0].name,
+                            sort: originConfig.sortType || 'asc',
+                            filters: getBodyFilters(filters),
+                            testPage: {
+                                pageNum: 1,
+                                pageSize: 9999999,
+                            }
+                        };
+        
+                        let res = yield call(service.fetch, {
+                            url: URLS.CHART_DATAVIEW_OPTION,
+                            body: body,
+                            timeout: 30000
+                        });
+                        if(res.code > 0) {
+                            res.data.valueList.list.forEach(l => {
+                                let r = {};
+                                viewColumns.forEach(c => {
+                                    let v = l[c.name];
+                                    if(c.type === 'time') {
+                                        v = moment(v).isValid() ? moment(v).format('YYYY-MM-DD'): v;
+                                    }
+                                    r[c.name] = v;
+                                });
+                                dataSource.push(r);
+                            })
+                        }else {
+                            console.error(res.msg);
                         }
-                    });;
-                    sortColumn = xAxis.column.value;
-                }else if(viewType === 'dataView') {
-                    columns = dataViewConfig.viewColumns;
-                    sortColumn = dataViewConfig.sortColumn.key;
-                }
-
-                if(columns.length === 0) {
-                    // message.error('');
-                    return false;
-                }
-                columnListName = columns.map(c => c.name);
-
-                const body = {
-                    id: code,
-                    columnListName: columnListName,
-                    sortColumn: sortColumn,
-                    sort: 'asc',
-                    filters: getBodyFilters(filters),
-                    testPage: {
-                        pageNum: page || 1,
-                        pageSize: pageSize || 25,
+                        break;
                     }
-                };
+                    case 'aggregateTable': {
+                        const { originConfig, data, group1Name, group2Name, group1s, group2s } = chartOption;
+                        const { groupBy, statistics: statisticsNames } = originConfig;
 
-                yield put({ type: 'dataList/setField', name: 'loading', value: true });
-                let res = yield call(service.fetch, {
-                    url: URLS.CHART_DATAVIEW_OPTION,
-                    body: body,
-                    timeout: 30000
-                });
-                if(res.code > 0) {
+                        let statistics = statisticsNames.map(s => {
+                            if(!s.name) {
+                                let f = STATISTICS_OPTION.find(o => o.value === s);
+                                return !!f ? {
+                                    name: f.value,
+                                    label: f.label
+                                } : null;
+                            }
+                            return s
+                        }).filter(s => !!s);
 
-                    const { valueList } = res.data;
-                    const { list: dataSource, pageSize, total } = valueList;
+                        columns = groupBy.map((g, i) => ({ title: g.label, dataIndex: `groupBy${i+1}`, type: 'string' })).concat(statistics.map(s => ({ title: s.label, dataIndex: s.name, type: 'scale' })));
 
-                    yield put({ type: 'dataList/setFields', fields: [
-                        { name: 'columns', value: columns },
-                        { name: 'dataSource', value: dataSource },
-                        { name: 'pageSize', value: pageSize },
-                        { name: 'total', value: total }
-                    ] });
-                }else {
-                    message.error('请求列表数据失败: ' + res.msg);
-                    // yield put({ type: 'silentSetField', name: 'chartOption', value: {} });
+                        if(!group1Name) { // 无分组
+                            let obj = {};
+                            statistics.forEach(s => {
+                                obj[s.name] = data[s.name];
+                            });
+                            dataSource.push(obj);
+                        }else {
+                            if(!group2Name) { // 只有一个分组
+                                dataSource = group1s.map((g, i) => {
+                                    let obj = {};
+                                    obj['groupBy1'] = g;
+                                    statistics.forEach(s => {
+                                        obj[s.name] = data[i][s.name];
+                                    });
+                                    return obj;
+                                });
+                            }else { // 有两个分组
+                                group1s.forEach((g1, i1) => {
+                                    let d = data[i1];
+                                    group2s.forEach((g2, i2) => {
+                                        let obj = {};
+                                        obj['groupBy1'] = g1;
+                                        obj['groupBy2'] = g2;
+                                        statistics.forEach(s => {
+                                            obj[s.name] = d.data[i2][s.name];
+                                        })
+                                        dataSource.push(obj);
+                                    })
+                                });
+                            }
+                        }
+                        console.log(columns, dataSource);
+                        break;
+                    }
+                    case 'indicator': {
+                        let { originConfig, data } = chartOption;
+                        let { xAxis, yAxis, otherColumn } = (originConfig || {});
+                        columns = [{
+                            title: xAxis.column.label,
+                            dataIndex: 'xAxis',
+                            type: xAxis.column.type
+                        }, {
+                            title: `${yAxis.column.label}${yAxis.gauge.value ? `(${yAxis.gauge.label})` : ''}`,
+                            dataIndex: 'yAxis',
+                            type: yAxis.column.type
+                        }].concat(otherColumn.map((c, i) => ({
+                            title: c.label,
+                            dataIndex: `other${i}`,
+                            type: c.type
+                        })));
+                        dataSource = data.map(d => {
+                            let obj = {};
+                            obj['xAxis'] = d.name;
+                            obj['yAxis'] = d.value;
+                            d.others.forEach((o, i) => {
+                                obj[`other${i}`] = o.value;
+                            })
+                            return obj;
+                        });
+                        break;
+                    }
+                    default:
+                        break;
                 }
+                return { columns, dataSource};
             }catch(e) {
-                message.error('请求数据列表失败: ' + e.message);
-            }finally {
-                yield put({ type: 'dataList/setField', name: 'loading', value: false });
+                message.error('解析数据失败: ' + e.message);
+                return { columns: [], dataSource: []}
             }
         },
     },

+ 18 - 172
src/models/dashboardDesigner.js

@@ -712,37 +712,9 @@ export default {
                 yield put({ type: 'dataList/setField', name: 'loading', value: false });
             }
         },
-        /**
-         * 后台导出方案-已废弃
-         */
-        // *exportToExcel(action, { select, call, put }) {
-        //     const dashboardDesigner = yield select(state => state.present.dashboardDesigner);
-        //     const { code, name, dataSources, filters } = dashboardDesigner;
-        //     try {
-        //         let body = {
-        //             dashboardId: code,
-        //             dashboardName: name,
-        //             data: dataSources.map(d => {
-        //                 let { code } = d;
-        //                 return {
-        //                     dataSourceId: code,
-        //                     filter: getBodyFilters(getTrueFilters({ dataSourceCode: code }, filters))
-        //                 }
-        //             }),
-        //         }
-        //         yield call(service.fetch, {
-        //             url: URLS.DASHBOARD_EXPORT,
-        //             requestType: 'file',
-        //             fileName: name,
-        //             body,
-        //         })
-        //     }catch(e) {
-        //         message.error('报表导出错误: ' + e);
-        //     }
-        // },
-        *exportToExcel(action, { select, call, put }) {
+        *exportToExcel(action, { select, take, put }) {
             const dashboardDesigner = yield select(state => state.present.dashboardDesigner);
-            const { name, creatorCode, filters, items } = dashboardDesigner;
+            const { name, filters, items } = dashboardDesigner;
             try {
                 yield put({ type: 'setField', name: 'loading', value: true });
 
@@ -750,9 +722,6 @@ export default {
                 for(let i = 0; i < items.length; i++) {
                     let item = items[i];
                     let { chartCode, name: itemName, chartOption, viewType, chartType, content } = item;
-                    let option = chartOption ? (chartOption.baseOption || {}) : {};
-                    let { originConfig, xAxis, series } = option;
-                    let { xAxis: oxAxis, yAxis: oyAxis, groupBy: ogroupBy } = (originConfig || {});
                     let header;
                     let columns = [];
                     let rows = [];
@@ -763,146 +732,23 @@ export default {
                         string: 'String'
                     };
                     if(viewType === 'chart') {
-                        if(chartType === 'bar' || chartType === 'line') {
-                            columns = [{
-                                name: `${oxAxis.column.label}${oxAxis.granularity.value ? `(${oxAxis.granularity.label})` : ''}`,
-                                width: 150,
-                                type: 'String'
-                            }, {
-                                name: `${oyAxis.column.label}${oyAxis.gauge.value ? `(${oyAxis.gauge.label})` : ''}`,
-                                width: 100,
-                                type: 'Number'
-                            }];
-                            if(ogroupBy && ogroupBy.key) {
-                                columns.push({
-                                    name: ogroupBy.label,
-                                    width: 150,
-                                    type: 'String'
-                                });
-                            }
-                            xAxis[0].data.forEach((d, i) => {
-                                if(ogroupBy && ogroupBy.key) {
-                                    series.forEach(xs => {
-                                        rows.push([d, xs.data[i], xs.name]);
-                                    })
-                                }else {
-                                    rows.push([d, series[0].data[i]])
-                                }
-                            })
-                        }else if(chartType === 'pie') {
-                            columns = [{
-                                name: `${oxAxis.column.label}${oxAxis.granularity.value ? `(${oxAxis.granularity.label})` : ''}`,
-                                width: 150,
-                                type: 'String'
-                            }, {
-                                name: `${oyAxis.column.label}${oyAxis.gauge.value ? `(${oyAxis.gauge.label})` : ''}`,
-                                width: 100,
-                                type: 'Number'
-                            }];
-                            rows = series[0].data.map(d => ([d.name, d.value]))
-                        }else if(chartType === 'scatter') {
-                            columns = [{
-                                name: oxAxis.column.label,
-                                width: 80,
-                                type: 'Number'
-                            }, {
-                                name: `${oyAxis.column.label}${oyAxis.gauge.value ? `(${oyAxis.gauge.label})` : ''}`,
-                                width: 80,
-                                type: 'Number'
-                            }];
-                            if(ogroupBy && ogroupBy.key) {
-                                columns.push({
-                                    name: ogroupBy.label,
-                                    width: 100,
-                                    type: 'String'
-                                });
-                            }
-                            series.forEach(xs => {
-                                xs.data.forEach(xd => {
-                                    if(ogroupBy && ogroupBy.key) {
-                                        rows.push([xd[0], xd[1], xs.name]);
-                                    }else {
-                                        rows.push([xd[0], xd[1]]);
-                                    }
-                                });
-                            })
-                        }else if(chartType === 'dataView') {
-                            let { viewColumns } = chartOption.originConfig || {};
-                            columns = viewColumns.map(c => ({
-                                name: c.label,
-                                width: 100,
+                        let sync = yield put({ type: 'chartDesigner/getChartTableData',
+                            chartCode, chartType, chartOption, filters: getTrueFilters(item, filters) });
+                        yield take('chartDesigner/getChartTableData/@@end');
+                        yield sync.then(tableData => {
+                            let { columns: tcolumns, dataSource: tdatasource } = tableData;
+                            columns = tcolumns.map(c => ({
+                                name: c.title,
+                                width: 120,
                                 type: TYPES[c.type]
                             }));
-                            const res = yield call(service.fetch, {
-                                url: URLS.CHART_OPTION,
-                                allow: true,
-                                body: {
-                                    dashboardCreatorId: creatorCode,
-                                    chartId: chartCode,
-                                    filters: getBodyFilters(getTrueFilters(item, filters)),
-                                    testPage: {
-                                        pageNum: 1,
-                                        pageSize: 99999, 
-                                    } 
-                                },
-                                timeout: 30000
-                            });
-                            if(res.code > 0) {
-                                res.data.valueList.list.forEach(l => {
-                                    let r = [];
-                                    viewColumns.forEach(c => {
-                                        let v = l[c.name];
-                                        if(c.type === 'time') {
-                                            v = moment(v).format('YYYY-MM-DD')
-                                        }
-                                        r.push(v);
-                                    });
-                                    rows.push(r);
-                                })
-                            }else {
-                                console.error(res.msg);
-                            }
-                        }else if(chartType === 'aggregateTable') {
-                            let { originConfig, data, group1Name, group2Name, group1s, group2s } = chartOption;
-                            let { targetColumn, groupBy, statistics } = (originConfig || {});
-                            header = `分析目标:${targetColumn.label}`
-                            columns = groupBy.map(g => ({ name: g.label, width: 100, type: TYPES[g.type] })).concat(statistics.map(s => ({ name: s.label, width: 100, type: 'Number' })));
-
-                            if(!group1Name) { // 无分组
-                                rows = [statistics.map(s => data[s.name])];
-                            }else {
-                                if(!group2Name) { // 只有一个分组
-                                    rows = group1s.map((g, i) => [g].concat(statistics.map(s => data[i][s.name])));
-                                }else { // 有两个分组
-                                    group1s.forEach((g1, i1) => {
-                                        let d = data[i1];
-                                        group2s.forEach((g2, i2) => {
-                                            let arr = statistics.map(s => d.data[i2][s.name]);
-                                            rows.push([g1, g2].concat(arr));
-                                        })
-                                    });
-                                }
+                            rows = tdatasource.map(d => {
+                                return tcolumns.map(c => d[c.dataIndex])
+                            })
+                            if(chartType === 'aggregateTable') {
+                                header = `分析目标:${chartOption.originConfig.targetColumn.label}`
                             }
-                        }else if(chartType === 'indicator') {
-                            let { originConfig, data } = chartOption;
-                            let { xAxis, yAxis, otherColumn } = (originConfig || {});
-                            columns = [{
-                                name: xAxis.column.label,
-                                width: 100,
-                                type: 'String'
-                            }, {
-                                name: `${yAxis.column.label}${yAxis.gauge.value ? `(${yAxis.gauge.label})` : ''}`,
-                                width: 100,
-                                type: 'Number'
-                            }].concat(otherColumn.map(c => ({
-                                name: c.label,
-                                width: 100,
-                                type: 'String'
-                            })));
-                            rows = data.map(d => {
-                                return [d.name, d.value].concat(d.others.map(o => o.value))
-                            });
-                        }
+                        });
                     }else if(viewType === 'richText') {
                         content = content || '';
                         columns = [{
@@ -922,8 +768,8 @@ export default {
                         rows
                     });
                 }
-                let e = new Exportor({ sheets }, `${name}.xls`);
-                e.export();
+                let e = yield new Exportor({ sheets }, `${name}.xls`);
+                yield e.export();
             }catch(e) {
                 message.error('报表导出错误: ' + e);
             }finally {

+ 40 - 42
src/models/parseChartOption.js

@@ -1,12 +1,12 @@
 /**
  * 将请求返回的图表展示数据解析为前台展示用的config
  */
-import moment from 'moment'
-import EllipsisTooltip from '../components/common/ellipsisTooltip/index'
-import { deepAssign, numberFormat } from '../utils/baseUtils'
-import STATISTICS_OPTION from '../components/chartDesigner/sections/statisticsOption.json'
-import themes from '../components/chartDesigner/sections/style/theme/index'
-import EChartsMedia from './EChartsMedia'
+import moment from 'moment';
+import EllipsisTooltip from '../components/common/ellipsisTooltip/index';
+import { deepAssign, numberFormat } from '../utils/baseUtils';
+import STATISTICS_OPTION from '../components/chartDesigner/sections/statisticsOption.json';
+import themes from '../components/chartDesigner/sections/style/theme/index';
+import EChartsMedia from './EChartsMedia';
 
 export default function(viewType, data, chartConfig, themeName, styleConfig) {
     if(!data) {
@@ -74,9 +74,7 @@ function barOption(data, barConfig, themeConfig, styleConfig) {
 
     let option = deepAssign({
         originConfig: {
-            xAxis,
-            yAxis,
-            groupBy,
+            ...barConfig
         },
         tooltip : {
             trigger: "axis",
@@ -105,15 +103,16 @@ function barOption(data, barConfig, themeConfig, styleConfig) {
                 let xv = d;
                 if(gv === 'halfYear') {
                     let arr = d.split('-H');
-                    xv = arr[0] + ['上半年', '下半年'][arr[1] - 1]
+                    xv = `${arr[0] || '-'} ${['上半年', '下半年'][arr[1] - 1]}`;
                 }else if(gv === 'month') {
-                    xv = d.replace('-M', '-');
+                    let arr = d.split('-');
+                    xv = `${arr[0] || '-'}/${arr[1]}`;
                 }else if(gv === 'quarter') {
                     let arr = d.split('-');
-                    xv = arr[0] + '-' + ['一', '二', '三', '四'][arr[1] - 1] + '季度'
+                    xv = `${arr[0] || '-'} ${['一', '二', '三', '四'][arr[1] - 1] + '季度'}`;
                 }else if(gv === 'week') {
                     let arr = d.split('-');
-                    xv = arr[0] + '-' + arr[1] + '周'
+                    xv = (arr[0] || '-') + ' ' + arr[1] + '周'
                 }
                 return xv;
             }),
@@ -177,9 +176,7 @@ function lineOption(data, lineConfig, themeConfig, styleConfig) {
 
     let option = deepAssign({
         originConfig: {
-            xAxis,
-            yAxis,
-            groupBy
+            ...lineConfig
         },
         tooltip : {
             trigger: "axis",
@@ -209,15 +206,16 @@ function lineOption(data, lineConfig, themeConfig, styleConfig) {
                 let xv = d;
                 if(gv === 'halfYear') {
                     let arr = d.split('-H');
-                    xv = arr[0] + ['上半年', '下半年'][arr[1] - 1]
+                    xv = `${arr[0] || '-'} ${['上半年', '下半年'][arr[1] - 1]}`;
                 }else if(gv === 'month') {
-                    xv = d.replace('-M', '-');
+                    let arr = d.split('-');
+                    xv = `${arr[0] || '-'}/${arr[1]}`;
                 }else if(gv === 'quarter') {
                     let arr = d.split('-');
-                    xv = arr[0] + '-' + ['一', '二', '三', '四'][arr[1] - 1] + '季度'
+                    xv = `${arr[0] || '-'} ${['一', '二', '三', '四'][arr[1] - 1] + '季度'}`;
                 }else if(gv === 'week') {
                     let arr = d.split('-');
-                    xv = arr[0] + '-' + arr[1] + '周'
+                    xv = (arr[0] || '-') + ' ' + arr[1] + '周'
                 }
                 return xv;
             }),
@@ -271,8 +269,7 @@ function pieOption(data, pieConfig, themeConfig, styleConfig) {
     let dataList = (data.serieses || [{ value: [] }])[0].value;
     let option = deepAssign({
         originConfig: {
-            xAxis,
-            yAxis,
+            ...pieConfig
         },
         tooltip : {
             trigger: 'item',
@@ -319,15 +316,16 @@ function pieOption(data, pieConfig, themeConfig, styleConfig) {
                     let gv= pieConfig.xAxis.granularity.value;
                     if(gv === 'halfYear') {
                         let arr = v.name.split('-H');
-                        obj.name = arr.length === 2 ? arr[0] + ['上半年', '下半年'][arr[1] - 1] : v.name;
+                        obj.name = `${arr[0] || '-'} ${['上半年', '下半年'][arr[1] - 1]}`;
                     }else if(gv === 'month') {
-                        obj.name = v.name.replace('-M', '-');
+                        let arr = v.name.split('-');
+                        obj.name = `${arr[0] || '-'}/${arr[1]}`;
                     }else if(gv === 'quarter') {
                         let arr = v.name.split('-');
-                        obj.name = arr.length === 2 ? arr[0] + '-' + ['一', '二', '三', '四'][arr[1] - 1] + '季度' : v.name
+                        obj.name = `${arr[0] || '-'} ${['一', '二', '三', '四'][arr[1] - 1] + '季度'}`;
                     }else if(gv === 'week') {
                         let arr = v.name.split('-');
-                        obj.name = arr.length === 2 ? arr[0] + '-' + arr[1] + '周' : v.name
+                        obj.name = (arr[0] || '-') + ' ' + arr[1] + '周'
                     }
                 }
                 return obj;
@@ -355,9 +353,7 @@ function scatterOption(data, scatterConfig, themeConfig, styleConfig) {
     
     let option = deepAssign({
         originConfig: {
-            xAxis,
-            yAxis,
-            groupBy
+            ...scatterConfig
         },
         tooltip: {
             trigger: 'axis',
@@ -420,10 +416,16 @@ function aggregateTableOption( data, aggregateTableConfig, themeConfig, styleCon
     const { targetColumn, groupBy, statistics: statisticsNames } = aggregateTableConfig;
     const { direction } = styleConfig;
 
-    let statistics = STATISTICS_OPTION.filter(o => statisticsNames.indexOf(o.value) !== -1).map(s => ({
-            name: s.value,
-            label: s.label
-        })),
+    let statistics = statisticsNames.map(s => {
+            if(!s.name) {
+                let f = STATISTICS_OPTION.find(o => o.value === s);
+                return !!f ? {
+                    name: f.value,
+                    label: f.label
+                } : null;
+            }
+            return s
+        }).filter(s => !!s),
         group1Name = groupBy.length > 0 ? groupBy[0].key : null,
         group2Name = groupBy.length > 1 ? groupBy[1].key : null,
         group1s = [],
@@ -488,9 +490,7 @@ function aggregateTableOption( data, aggregateTableConfig, themeConfig, styleCon
 
     let option = {
         originConfig: {
-            targetColumn,
-            groupBy,
-            statistics,
+            ...aggregateTableConfig
         },
         themeConfig,
         targetColumn,
@@ -503,6 +503,7 @@ function aggregateTableOption( data, aggregateTableConfig, themeConfig, styleCon
         data: tableData
     };
 
+    console.log(option);
     return option;
 }
 
@@ -514,7 +515,7 @@ function dataViewOption(data, dataViewConfig, themeConfig, styleConfig) {
 
     let option = {
         originConfig: {
-            viewColumns
+            ...dataViewConfig
         },
         themeConfig,
         columns: columns.map(c => {
@@ -548,13 +549,10 @@ function dataViewOption(data, dataViewConfig, themeConfig, styleConfig) {
 }
 
 function indicatorOption(data, indicatorConfig, themeConfig, styleConfig) {
-    const { xAxis, yAxis, otherColumn, threshold } = indicatorConfig;
+    const { xAxis, yAxis, otherColumn } = indicatorConfig;
     let option = {
         originConfig: {
-            xAxis,
-            yAxis,
-            otherColumn,
-            threshold
+            ...indicatorConfig
         },
         themeConfig,
         data: (data.serieses || []).map(d => ({

+ 1 - 1
src/routes/mainLayout.less

@@ -1,5 +1,5 @@
 html,body,#root{
-    width: 100%;
+    width: 100% !important;
     height: 100%;
     overflow: hidden;
 }