Преглед изворни кода

图表列表界面显示缩略图/数据源保存时传入选中数据连接id以为password赋值/导航栏预添加用户信息列/调整数据源列设置表格宽度,优化拖动效果

zhuth пре 7 година
родитељ
комит
db0aecddc0

+ 1 - 1
src/components/chart/list.jsx

@@ -121,7 +121,7 @@ class ChartList extends React.Component {
                                 dispatch({ type: 'chartDesigner/reset' });
                                 dispatch({ type: 'main/redirect', path: '/chart/' + l.code });
                             }}>
-                                <Thumbnail code={l.code} />
+                                <Thumbnail code={l.code} option={l.chartOption}/>
                             </Row>
                             <Row className='desc'>
                                 <Ellipsis tooltip={l.description.length > 16} lines={2}>{

+ 188 - 0
src/components/chart/resolveChartOption.js

@@ -0,0 +1,188 @@
+export default (config) => {
+    const { viewType, option } = config;
+    let o;
+    switch(viewType) {
+        case 'bar': {
+            o = barConfig(option);
+            break;
+        }
+        case 'pie': {
+            o = pieConfig(option);
+            break;
+        }
+        case 'line': {
+            o = lineConfig(option);
+            break;
+        }
+        case 'scatter': {
+            o = scatterConfig(option);
+            break;
+        }
+        case 'aggregateTable': {
+            o = tableConfig(option);
+            break;
+        }case 'dataView' : {
+            o = tableConfig(option);
+            break;
+        }
+        default:{
+            o = {};
+            break;
+        }
+    }
+    return o;
+}
+
+function barConfig(option) {
+    const { xAxis, serieses, xTitle, yTitle } = option;
+
+    let o = {
+        animation: false,
+        legend: {show: false},
+        grid: {
+            left: 0,
+            right: 0,
+            top: 0,
+            bottom: 0,
+            containLabel: false
+        },
+        xAxis: [{
+            type: 'category',
+            boundaryGap: false,
+            data: xAxis,
+            name: xTitle || '横轴',
+            show: false
+        }],
+        yAxis: [{
+            name: yTitle || '纵轴',
+            type: 'value',
+            show: false
+        }],
+        series: serieses.map(s => {
+            return {
+                name: s.name,
+                type: 'bar',
+                data: s.value,
+                showSymbol: false,
+                silent: true
+            }
+        }) 
+    }
+    return o;
+}
+
+function pieConfig(option) {
+
+    const { xAxis, columnName, serieses } = option;
+
+    let o = {
+        animation: false,
+        legend: {show: false},
+        series : [
+            {
+                name: columnName,
+                type: 'pie',
+                // radius : '55%',
+                // center: ['50%', '60%'],
+                data: serieses[0].value,
+                label: { show: false },
+                labelLine: { show: false },
+                silent: true
+            }
+        ]
+    };
+    return o;
+}
+
+function lineConfig(option) {
+    const { serieses, xTitle, yTitle } = option;
+
+    let o = {
+        animation: false,
+        grid: {
+            left: 0,
+            right: 0,
+            top: 0,
+            bottom: 0,
+            containLabel: false
+        },
+        legend: {show: false},
+        xAxis:  {
+            name: xTitle,
+            type: 'time',
+            show: false
+        },
+        yAxis: {
+            name: yTitle,
+            type: 'value',
+            show: false
+        },
+        series: serieses.map(s => {
+            return {
+                name: s.name,
+                type: 'line',
+                data: s.mdata.map(m => {
+                    return [m.date, m.value]
+                }),
+                showSymbol: false,
+                silent: true
+            }
+        })
+    };
+
+    return o;
+}
+
+function scatterConfig(option) {
+    const { serieses, xTitle, yTitle } = option;
+    let o = {
+        animation: false,
+        grid: {
+            left: 0,
+            right: 0,
+            top: 0,
+            bottom: 0,
+            containLabel: false
+        },
+        xAxis : {
+            type : 'value',
+            name: xTitle,
+            scale:true,
+            splitLine: {
+                show: false
+            },
+            show: false
+        },
+        yAxis : {
+            type : 'value',
+            name: yTitle,
+            scale:true,
+            splitLine: {
+                show: false
+            },
+            show: false
+        },
+        series : serieses.map(s => {
+            return {
+                name: s.name,
+                type: 'scatter',
+                data: s.mdata.map(m => {
+                    return [m.date, m.value]
+                }),
+                silent: true
+            }
+        })
+    };
+    return o;
+}
+
+function tableConfig(option) {
+    const { columns, data } = option;
+    let o = {
+        columns,
+        data: data.map((d, i) => {
+            return { ...d, key: i}
+        })
+    };
+    return o;
+}

+ 3 - 164
src/components/chart/thumbnail.jsx

@@ -1,174 +1,13 @@
 import React from 'react'
 import Echarts from 'echarts-for-react'
+import resolveChartOption from './resolveChartOption'
 
-const Thumbnail = ({ code }) => {
-    let option1 = {
-        xAxis: {
-            type: 'category',
-            boundaryGap: false,
-            data: ['周一','周二','周三','周四','周五','周六','周日'],
-            show: false
-        },
-        grid: {
-            left: 0,
-            right: 0,
-            top: 0, 
-            bottom: 0,
-            containLabel: false
-        },
-        yAxis: {
-            show: false,
-            type: 'value'
-        },
-        series: [
-            {
-                name:'邮件营销',
-                type:'line',
-                data:[120, 132, 101, 134, 90, 230, 210],
-                showSymbol: false
-            },
-            {
-                name:'联盟广告',
-                type:'line',
-                data:[220, 182, 191, 234, 290, 330, 310],
-                showSymbol: false
-            },
-            {
-                name:'视频广告',
-                type:'line',
-                data:[150, 232, 201, 154, 190, 330, 410],
-                showSymbol: false
-            },
-            {
-                name:'直接访问',
-                type:'line',
-                data:[320, 332, 301, 334, 390, 330, 320],
-                showSymbol: false
-            },
-            {
-                name:'搜索引擎',
-                type:'line',
-                data:[820, 932, 901, 934, 1290, 1330, 1320],
-                showSymbol: false
-            }
-        ]
-    };
-    let option2 = {
-        xAxis: {
-            type: 'category',
-            boundaryGap: false,
-            data: ['周一','周二','周三','周四','周五','周六','周日'],
-            show: false
-        },
-        grid: {
-            left: 0,
-            right: 0,
-            top: 0, 
-            bottom: 0,
-            containLabel: false
-        },
-        yAxis: {
-            show: false,
-            type: 'value'
-        },
-        series: [
-            {
-                name:'邮件营销',
-                type:'bar',
-                data:[120, 132, 101, 134, 90, 230, 210],
-                showSymbol: false,
-                silent: true
-            },
-            {
-                name:'联盟广告',
-                type:'bar',
-                data:[220, 182, 191, 234, 290, 330, 310],
-                showSymbol: false,
-                silent: true
-            },
-            {
-                name:'视频广告',
-                type:'bar',
-                data:[150, 232, 201, 154, 190, 330, 410],
-                showSymbol: false,
-                silent: true
-            },
-            {
-                name:'直接访问',
-                type:'bar',
-                data:[320, 332, 301, 334, 390, 330, 320],
-                showSymbol: false,
-                silent: true
-            },
-            {
-                name:'搜索引擎',
-                type:'bar',
-                data:[820, 932, 901, 934, 1290, 1330, 1320],
-                showSymbol: false,
-                silent: true
-            }
-        ]
-    };
-    let option3 = {
-        series : [
-            {
-                name: '访问来源',
-                type: 'pie',
-                data:[
-                    {value:335, name:'直接访问'},
-                    {value:310, name:'邮件营销'},
-                    {value:234, name:'联盟广告'},
-                    {value:135, name:'视频广告'},
-                    {value:1548, name:'搜索引擎'}
-                ],
-                label: {
-                    show: false
-                },
-                labelLine: {
-                    show: false
-                },
-                silent: true
-            }
-        ]
-    };
-    let option4 = {
-        xAxis: {
-            show: true
-        },
-        yAxis: {
-            show: true
-        },
-        grid: {
-            left: 0,
-            right: 0,
-            top: 0, 
-            bottom: 0,
-            containLabel: false
-        },
-        series: [{
-            data: [
-                [10.0, 8.04],
-                [8.0, 6.95],
-                [13.0, 7.58],
-                [9.0, 8.81],
-                [11.0, 8.33],
-                [14.0, 9.96],
-                [6.0, 7.24],
-                [4.0, 4.26],
-                [12.0, 10.84],
-                [7.0, 4.82],
-                [5.0, 5.68]
-            ],
-            type: 'scatter',
-            silent: true
-        }]
-    };
-    let option = [option1, option2, option3, option4]
+const Thumbnail = ({ code, option }) => {
     return (
         <div style={{ width: '100%', height: '100%' }}>
             <Echarts
                 key={code}
-                option={option[0]}
+                option={resolveChartOption(option || {})}
                 className='rc-echarts'
                 style={{height: '100%'}}
             />

+ 3 - 2
src/components/chartDesigner/layout.jsx

@@ -10,9 +10,10 @@ class ChartDesigner extends React.Component {
     componentDidMount() {
         const { dispatch } = this.props;
         const { code } = this.props.match.params;
+        dispatch({ type: 'chartDesigner/reset' });
         if(code !== 'create') {
-            dispatch({ type: 'chart/remoteDetail', code: code })
-            dispatch({ type: 'chart/remoteGroupList', code: code })
+            dispatch({ type: 'chart/remoteDetail', code: code });
+            dispatch({ type: 'chart/remoteGroupList', code: code });
         }
     }
     render() {

+ 30 - 21
src/components/common/navigator.jsx

@@ -16,27 +16,36 @@ class Navigator extends React.Component {
 
         const { main } = this.props;
 
-        return <Menu
-            className='navigator-menu'
-            selectedKeys={[main.currentPage]}
-            mode="horizontal"
-        >     
-            <Menu.Item className='nav-page' key="home">
-                <Link to='/home'><Icon type="home" />我的</Link>
-            </Menu.Item>
-            <Menu.Item className='nav-page' key="dashboard">
-                <Link to='/dashboard'><Icon type="desktop" />报告与看板</Link>
-            </Menu.Item>
-            <Menu.Item className='nav-page' key="chart">
-                <Link to='/chart'><Icon type="area-chart" />图表</Link>
-            </Menu.Item>
-            <Menu.Item className='nav-page' key="datasource">
-                <Link to='/datasource'><Icon type="database" />数据源</Link>
-            </Menu.Item>
-            <Menu.Item className='nav-page' key="modeling">
-                <Link to='#'><Icon type="tool" />建模分析</Link>
-            </Menu.Item>
-        </Menu>
+        return <div className='navigator'>
+            <div className='navigator-left'>
+            </div>
+            <div className='navigator-content'>
+                <Menu
+                    className='navigator-menu'
+                    selectedKeys={[main.currentPage]}
+                    mode="horizontal"
+                >     
+                    <Menu.Item className='nav-page' key="home">
+                        <Link to='/home'><Icon type="home" />我的</Link>
+                    </Menu.Item>
+                    <Menu.Item className='nav-page' key="dashboard">
+                        <Link to='/dashboard'><Icon type="desktop" />报告与看板</Link>
+                    </Menu.Item>
+                    <Menu.Item className='nav-page' key="chart">
+                        <Link to='/chart'><Icon type="area-chart" />图表</Link>
+                    </Menu.Item>
+                    <Menu.Item className='nav-page' key="datasource">
+                        <Link to='/datasource'><Icon type="database" />数据源</Link>
+                    </Menu.Item>
+                    <Menu.Item className='nav-page' key="modeling">
+                        <Link to='#'><Icon type="tool" />建模分析</Link>
+                    </Menu.Item>
+                </Menu>
+            </div>
+            <div className='navigator-right'>
+                <div></div>
+            </div>
+        </div>
     }
 }
 

+ 35 - 27
src/components/common/navigator.less

@@ -1,34 +1,42 @@
-.navigator-menu {
-    .nav-page {
-        border-bottom: none !important;
-        .hover {
+.navigator {
+    display: flex;
+    justify-content: space-between;
+    background: white;
+    height: 100%;
+    padding-bottom: 3px;
+    .navigator-menu {
+        border-bottom: none;
+        .nav-page {
+            border-bottom: none !important;
+            .hover {
+                ::after {
+                    width: calc(100% - 8px);
+                }
+            }
             ::after {
-                width: calc(100% - 8px);
+                content: ' ';
+                display: block;
+                position: absolute;
+                left: 0;
+                right: 0;
+                bottom: 0;
+                width: 0;
+                height: 2px;
+                margin: -2px auto;
+                box-shadow: inset 0 2px #1890ff;
+                transition: width .25s cubic-bezier(0.31, 0.93, 1, 1);
             }
         }
-        ::after {
-            content: ' ';
-            display: block;
-            position: absolute;
-            left: 0;
-            right: 0;
-            bottom: 0;
-            width: 0;
-            height: 2px;
-            margin: -2px auto;
-            box-shadow: inset 0 2px #1890ff;
-            transition: width .25s cubic-bezier(0.31, 0.93, 1, 1);
-        }
-    }
-    .ant-menu-item-selected {
-        ::after {
-            width: calc(100% - 8px);
-            box-shadow: inset 0 2px #1890ff;
+        .ant-menu-item-selected {
+            ::after {
+                width: calc(100% - 8px);
+                box-shadow: inset 0 2px #1890ff;
+            }
         }
-    }
-    .ant-menu-item-active {
-        ::after {
-            width: calc(100% - 8px);
+        .ant-menu-item-active {
+            ::after {
+                width: calc(100% - 8px);
+            }
         }
     }
 }

+ 8 - 3
src/components/datasource/columnConfig.jsx

@@ -1,5 +1,5 @@
 import React from 'react'
-import { Form, Input, Button, Select, Table, Checkbox, Divider, Icon, Popconfirm } from 'antd'
+import { Form, Input, Button, Select, Table, Checkbox, Switch, Divider, Icon, Popconfirm } from 'antd'
 import { connect } from 'dva'
 import COLUMN_TYPE from './columnType.json'
 import { Resizable } from 'react-resizable';
@@ -25,7 +25,7 @@ class DataSourceColumnConfig extends React.Component {
     constructor(props) {
         super(props);
         this.state = {
-            widths: [ 50, 80, 150, 80, 80, 150 ],
+            widths: [ 50, 100, 150, 100, 150, 200 ],
             visibleConfirm: false
         }
     }
@@ -178,7 +178,7 @@ class DataSourceColumnConfig extends React.Component {
             title: '别名',
             dataIndex: 'alias',
             key: 'alias',
-            width: widths[5],
+            // width: widths[5],
             render: (text, record) => {
                 return(
                     <Input
@@ -199,6 +199,11 @@ class DataSourceColumnConfig extends React.Component {
                     </Input>
                 )
             }
+        // }, {
+        //     title: '允许过滤',
+        //     dataIndex: 'filterable',
+        //     key: 'filterable',
+        //     render: (value, record) => <Switch />
         }].map((col, index) => ({
             ...col,
             onHeaderCell: column => ({

+ 1 - 0
src/components/datasource/dataConnectConfig.jsx

@@ -56,6 +56,7 @@ class DataConnectConfig extends React.Component {
                             // 选中项设置
                             dispatch({ type: 'dataConnect/setSelected', selected: l });
                             dispatch({ type: 'dataSource/setNewModelFields', fields: [
+                                { name: 'connectCode', value: l.code },
                                 { name: 'dbType', value: l.dbType },
                                 { name: 'address', value: l.address },
                                 { name: 'port', value: l.port },

+ 13 - 6
src/models/chart.js

@@ -121,6 +121,7 @@ export default {
                 console.log('请求图表列表', res);
                 if(!res.err && res.data.code > 0) {
                     let list = res.data.data.map(d => {
+                        let chartOption = d.chartOption ? JSON.parse(d.chartOption) : {};
                         return {
                             code:  d.chartId+'',
                             name: d.chartName,
@@ -128,7 +129,8 @@ export default {
                             creator: d.createBy,
                             createTime: d.createDate,
                             description: d.describes || '',
-                            groupCode: d.chartsGroup + ''
+                            groupCode: d.chartsGroup + '',
+                            chartOption: chartOption
                         }
                     })
                     yield put({ type: 'list', list: list });
@@ -176,6 +178,7 @@ export default {
                     let otherConfig = JSON.parse(resData.otherConfig || '{}');
                     let viewType = getViewType(resData.chartType);
                     let filters = JSON.parse(resData.filters || '[]');
+                    let chartOption = JSON.parse(resData.chartOption || '{}');
 
                     let data = {
                         code: resData.chartId,
@@ -190,6 +193,7 @@ export default {
                         description: resData.describes,
                         group: resData.chartsGroup+'',
                         filters: filters,
+                        chartOption: chartOption
                     }
 
                     if(viewType === 'bar') {
@@ -252,7 +256,7 @@ export default {
             try{
                 const chartDesigner = yield select(state => state.present.chartDesigner);
                 const { header, baseConfig, pieConfig, lineConfig, aggregateTableConfig, dataViewConfig,
-                    barConfig, scatterConfig, otherConfig, description, group } = chartDesigner;
+                    barConfig, scatterConfig, otherConfig, description, group, filters, chartOption } = chartDesigner;
                 let body = {
                     chartName: header.label,
                     dataId: baseConfig.dataSource,
@@ -260,7 +264,9 @@ export default {
                     describes: description,
                     style: '',
                     otherConfig: JSON.stringify(otherConfig),
-                    chartsGroup: group ? group : '-1'
+                    chartsGroup: group ? group : '-1',
+                    filters: JSON.stringify(filters),
+                    chartOption: JSON.stringify(chartOption),
                 }; // 基本属性
                 if(baseConfig.viewType === 'bar') {
                     body.chartType = 'Histogram';
@@ -322,17 +328,18 @@ export default {
             try{
                 const chartDesigner = yield select(state => state.present.chartDesigner);
                 const { filters, code, header, baseConfig, pieConfig, lineConfig, aggregateTableConfig, dataViewConfig,
-                    barConfig, scatterConfig, otherConfig, description, group } = chartDesigner;
+                    barConfig, scatterConfig, otherConfig, description, group, chartOption } = chartDesigner;
                 let body = {
                     chartId: code,
                     filters: JSON.stringify(filters),
                     chartName: header.label,
                     dataId: baseConfig.dataSource,
                     createBy: 'zhuth',
-                    describes: description,
+                    describes: description || '',
                     style: '',
                     otherConfig: JSON.stringify(otherConfig),
-                    chartsGroup: group ? group : '-1'
+                    chartsGroup: group+'' ? group : '-1',
+                    chartOption: JSON.stringify(chartOption)
                 }; // 基本属性
                 if(baseConfig.viewType === 'bar') {
                     body.chartType = 'Histogram';

+ 2 - 1
src/models/chartDesigner.js

@@ -45,6 +45,7 @@ export default {
             style: {},
             filters: [],
             chartOption: {},
+            dirty: false
         },
         columns: [],
         allPermission: [
@@ -116,7 +117,7 @@ export default {
         },
         reset(state, action) {
             let newState = Object.assign({}, state, state.originData);
-            return Object.assign({}, newState, {dirty: false});
+            return Object.assign({}, newState);
         },
         setDirty(state, action) {
             const { dirty } = action;

+ 1 - 0
src/models/dataSource.js

@@ -216,6 +216,7 @@ export default {
                     type: model.type,
                     createBy: 'admin',
                     dbConfig: {
+                        id: model.connectCode,
                         addrass: model.address,
                         port: model.port,
                         databaseType: model.dbType,