Browse Source

统一数据流action/柱状图横轴纵轴组件交互调整/删除测试文件

zhuth 7 years ago
parent
commit
b5ac8a8f0a

BIN
app/assets/yay.jpg


+ 0 - 9
app/components/Example.js

@@ -1,9 +0,0 @@
-import React from 'react';
-
-const Example = () => {
-  return <div>Example</div>;
-};
-
-Example.propTypes = {};
-
-export default Example;

+ 3 - 3
app/components/chartDesigner/charts/resolveChartOption.js

@@ -13,7 +13,7 @@ export default (config) => {
 }
 
 function barConfig(data) {
-    const { xAxis, serieses } = data;
+    const { xAxis, serieses, xTitle, yTitle, gauge } = data;
 
     let o = {
         tooltip : {
@@ -31,10 +31,10 @@ function barConfig(data) {
         xAxis: [{
             type: 'category',
             data: xAxis,
-            name: '横轴',
+            name: xTitle || '横轴',
         }],
         yAxis: [{
-            name: '纵轴',
+            name: yTitle?(`${yTitle}(${gauge})`) : '纵轴',
             type: 'value'
         }],
         series: serieses.map(s => {

+ 1 - 2
app/components/chartDesigner/header.jsx

@@ -1,6 +1,5 @@
 import React from 'react';
 import { Input, Select, Icon, Button } from 'antd';
-import emitter from '../../eventManger/ev';
 const Option = Select.Option;
 import './header.less';
 import { connect } from 'dva';
@@ -20,7 +19,7 @@ const Header = ({ chartDesigner, dispatch }) => {
                         }}
                     />}
                     onChange={(e) => {
-                        dispatch({ type: 'chartDesigner/setTitle', text: e.target.value });
+                        dispatch({ type: 'chartDesigner/setModel', name: 'header', value: { label: e.target.value } });
                     }}
                     value={chartDesigner.header.label}
                 />

+ 1 - 6
app/components/chartDesigner/layout.jsx

@@ -7,8 +7,6 @@ const SubMenu = Menu.SubMenu;
 import './layout.less';
 import ChartDesignerHeader from './header';
 import ChartDesignerContent from './content';
-import { connect } from 'dva';
-import chartDesigner from '../../models/chartDesigner';
 
 class ChartDesignerLayout extends React.Component {
     render() {
@@ -22,7 +20,4 @@ class ChartDesignerLayout extends React.Component {
         </Layout>
     }
 }
-function mapStateToProps({ present: { chartDesigner } }) {
-    return { chartDesigner: chartDesigner }
-}
-export default connect(mapStateToProps)(ChartDesignerLayout);
+export default ChartDesignerLayout;

+ 3 - 2
app/components/chartDesigner/sections/aggregateTableConfigForm.jsx

@@ -38,7 +38,8 @@ class AggregateTableConfigForm extends React.Component {
 						mode='multiple'
 						labelInValue={true}
 						onChange={(value) => {
-							props.dispatch({ type: 'chartDesigner/aggregateTable/setTargetColumn', targetColumn: value});
+							props.dispatch({ type: 'chartDesigner/setModel', name: 'aggregateTable', value: { ...props.chartDesigner.aggregateTable, targetColumn: value } });
+							
 						}}
 					>
 						{columns.map((c, i)=>{
@@ -51,7 +52,7 @@ class AggregateTableConfigForm extends React.Component {
 						value={props.chartDesigner.aggregateTable.statistics}
 						options={statisticsOptions.map((s)=>{return s.label})}
 						onChange={(value) => {
-							props.dispatch({ type: 'chartDesigner/aggregateTable/setStatistics', statistics: value});
+							props.dispatch({ type: 'chartDesigner/setModel', name: 'aggregateTable', value: { ...props.chartDesigner.aggregateTable, statistics: value } });
 						}}
 					/>
 				</FormItem>

+ 70 - 39
app/components/chartDesigner/sections/barConfigForm.jsx

@@ -5,6 +5,8 @@ const { Option } = Select;
 const { SubMenu, MenuItemGroup } = Menu;
 import { connect } from 'dva';
 import chartDesigner from '../../../models/chartDesigner';
+import gauge from './gauge.json';
+import granularity from './granularity.json';
 import './barConfigForm.less';
 
 const barConfigForm = ({ chartDesigner, dispatch, formItemLayout }) => {
@@ -27,68 +29,97 @@ const barConfigForm = ({ chartDesigner, dispatch, formItemLayout }) => {
 	return (
 		<Form hideRequiredMark={true}>
 			<FormItem label='横轴' {...formItemLayout}>
-				<Select
+				{/* <Select
 					value={chartDesigner.barConfig.xAxis}
 					allowClear={true}
 					placeholder='请选择...'
 					labelInValue={true}
 					onChange={(value) => {
-						dispatch({ type: 'chartDesigner/barConfig/setXAxis', xAxis: value});
+						dispatch({ type: 'chartDesigner/setModel', name: 'barConfig', value: { ...chartDesigner.barConfig, xAxis: value } });
 					}}
 				>
-					{columns.map((c, i)=>{
+					{columns.filter(c => ['ordinal', 'categorical'].indexOf(c.type)!=-1).map((c, i)=>{
 						return (<Option key={i} value={c.name}>{c.label}</Option>)
 					})}
-				</Select>
+				</Select> */}
+				<Cascader
+					className='barconfig-yaxis'
+					value={[chartDesigner.barConfig.xAxis.column.value, chartDesigner.barConfig.xAxis.granularity.value]}
+					allowClear={true}
+					options={columns.filter(c =>['ordinal', 'categorical', 'time'].indexOf(c.type) != -1).map((c, i)=>{
+						
+						return {
+							value: c.name,
+							label: c.label,
+							children: granularity[c.type]
+						}
+					})}
+					onChange={(value, items) => {
+						let column = {};
+						let granularity = {};
+						if(value.length > 0) {
+							column = { value: items[0].value, label: items[0].label };
+						}
+						if(items.length > 1) {
+							granularity = { value: items[1].value, label: items[1].label };
+						}
+						dispatch({ type: 'chartDesigner/setModel', name: 'barConfig', value: { ...chartDesigner.barConfig, xAxis: { column, granularity } } });
+					}}
+					displayRender={(label, selectedOptions) => {
+						let text = '';
+						let className = 'cascader-label';
+						if(label.length > 0) {
+							className += ' full-label';
+							text += label[0];
+							if(label.length > 1) {
+								text += '(' + label[1] + ')';
+							}
+						}else {
+							className += ' empty-label';
+							text = '请选择...';
+						}
+						return <div className={className}>{text}</div>;
+					}}
+				>
+				</Cascader>
 			</FormItem>
 			<FormItem label='纵轴' {...formItemLayout}>
 				<Cascader
-					className='barconfig-yxais'
-					value={chartDesigner.barConfig.yAxis}
+					className='barconfig-yaxis'
+					value={[chartDesigner.barConfig.yAxis.column.value, chartDesigner.barConfig.yAxis.gauge.value]}
 					allowClear={true}
-					placeholder='请选择...'
-					options={columns.map((c, i)=>{
-						// return (<Option key={i} value={c.name}>{c.label}</Option>)
+					options={columns.filter(c =>c.type == 'scale').map((c, i)=>{
 						return {
 							value: c.name,
 							label: c.label,
-							children: [{
-								value: 'sum',
-								label: '累计'
-							}, {
-								value: 'avg',
-								label: '平均值'
-							}, {
-								value: 'median',
-								label: '中位数'
-							}, {
-								value: 'count',
-								label: '计数'
-							}, {
-								value: 'distinctCount',
-								label: '不重复计数'
-							}, {
-								value: 'max',
-								label: '最大值'
-							}, {
-								value: 'min',
-								label: '最小值'
-							}]
+							children: gauge
 						}
 					})}
-					onChange={(value) => {
-						dispatch({ type: 'chartDesigner/barConfig/setYAxis', yAxis: value});
+					onChange={(value, items) => {
+						let column = {};
+						let gauge = {};
+						if(value.length > 0) {
+							column = { value: items[0].value, label: items[0].label };
+							gauge = { value: items[1].value, label: items[1].label };
+						}
+						dispatch({ type: 'chartDesigner/setModel', name: 'barConfig', value: { ...chartDesigner.barConfig, yAxis: { column, gauge } } });
 					}}
 					displayRender={(label, selectedOptions) => {
 						let menu = selectedOptions.length > 0 ? <Menu
-							defaultSelectedKeys={['sum']}
-							selectedKeys={['sum']}
+							selectedKeys={[chartDesigner.barConfig.yAxis.gauge.value]}
 							selectable={true}
 						>
 							{selectedOptions[0].children.map((c, i) => {
-								return <Menu.Item  data-value={c.value} key={i} onClick={(e) => {
+								return <Menu.Item  data-value={c.value} data-label={c.label} key={c.value} onClick={(e) => {
 									let value = e.domEvent.target.getAttribute('data-value');
-									dispatch({ type: 'chartDesigner/barConfig/setYAxis', yAxis: [chartDesigner.barConfig.yAxis[0], value] });
+									let label = e.domEvent.target.getAttribute('data-label');
+									dispatch({ type: 'chartDesigner/setModel', name: 'barConfig', value: { 
+										...chartDesigner.barConfig,
+										yAxis: {
+											column: chartDesigner.barConfig.yAxis.column,
+											gauge: { value, label }
+										}
+									}});
 									e.domEvent.stopPropagation();
 								}}>{c.label}</Menu.Item>
 							})}
@@ -101,9 +132,9 @@ const barConfigForm = ({ chartDesigner, dispatch, formItemLayout }) => {
 						</Dropdown>
 						: null;
 
-						return <div>
+						return <div className={`cascader-label ${tag?'full' : 'empty'}-label`}>
 							{tag}
-							<span>{label[0]}</span>
+							<span>{label[0] || '请选择...'}</span>
 						</div>
 					}}
 				>

+ 7 - 1
app/components/chartDesigner/sections/barConfigForm.less

@@ -1,6 +1,12 @@
-.barconfig-yxais {
+.barconfig-yaxis {
     .ant-cascader-picker-label {
         height: 100%;
         padding: 0 6px;
+        .cascader-label {
+            margin-left: 6px;
+        }
+        .empty-label {
+            color: #bfbfbf;
+        }
     }
 }

+ 3 - 16
app/components/chartDesigner/sections/baseConfigForm.jsx

@@ -28,7 +28,8 @@ class baseConfigForm extends React.Component {
 						value={props.chartDesigner.baseConfig.dataSource}
 						labelInValue={true}
 						onChange={(value) => {
-							props.dispatch({ type: 'chartDesigner/baseConfig/setDataSource', dataSource: value});
+							props.dispatch({ type: 'chartDesigner/setModel', name: 'baseConfig', value: {
+								...props.chartDesigner.baseConfig, dataSource: value } });
 						}}
 					>
 						{allDataSource.map((dataSource, i)=>{
@@ -42,7 +43,7 @@ class baseConfigForm extends React.Component {
 						value={props.chartDesigner.baseConfig.viewType.key}
 						dropdownMatchSelectWidth={false}
 						onChange={(value, item) => {
-							props.dispatch({ type: 'chartDesigner/baseConfig/setViewType', viewType: {key: value, label: item.title}});
+							props.dispatch({ type: 'chartDesigner/setModel', name: 'baseConfig', value: { ...props.chartDesigner.baseConfig, viewType: { key: value, label: item.title } } });
 						}}
 					>
 						<Option value="aggregateTable" title='总体统计数据表'>
@@ -100,20 +101,6 @@ class baseConfigForm extends React.Component {
 							</div>
 						</Option>
 					</Select>
-					{/* <Select 
-						value={props.chartDesigner.baseConfig.viewType}
-						labelInValue={true}
-						onChange={(value) => {
-							props.dispatch({ type: 'chartDesigner/baseConfig/setViewType', viewType: value});
-						}}
-					>
-						<Option value='aggregateTable'>总体统计数据表</Option>
-						<Option value='dataView'>个体统计数据表</Option>
-						<Option value='line'>折线图</Option>
-						<Option value='bar'>柱状图</Option>
-						<Option value='pie'>饼状图</Option>
-						<Option value='scatter'>散点图</Option>
-					</Select> */}
 				</FormItem>
 			</Form>
 		);

+ 1 - 1
app/components/chartDesigner/sections/dataViewConfigForm.jsx

@@ -20,7 +20,7 @@ class DataViewConfigForm extends React.Component {
 						value={props.chartDesigner.dataView.targetColumn}
 						labelInValue={true}
 						onChange={(value) => {
-							props.dispatch({ type: 'chartDesigner/dataView/setTargetColumn', targetColumn: value});
+							props.dispatch({ type: 'chartDesigner/setModel', name: 'dataView', value: { ...props.chartDesigner.dataView, targetColumn: value }});
 						}}
 					>
 						{columns.map((c, i)=>{

+ 53 - 32
app/components/chartDesigner/sections/filterBox.jsx

@@ -1,9 +1,9 @@
 import React from 'react';
 import PropTypes from 'prop-types';
-import { Form, Row, Col, Input, Icon, Button, Select, InputNumber, DatePicker } from 'antd';
+import { Modal, Form, Row, Col, Input, Icon, Button, Select, InputNumber, DatePicker } from 'antd';
 const FormItem = Form.Item;
 const SelectOption = Select.Option;
-import emitter from '../../../eventManger/ev';
+import { hashcode } from '../../../utils/baseUtils';
 import OPERATORS from './filterOperators.json';
 import './filterBox.less';
 
@@ -40,15 +40,13 @@ class FilterBox extends React.Component {
                 using: f.using
             }
         }));
-        // 对外提供接口
-        // 在组件装载完成后发布事件
-        this.eventEmitter = emitter.addListener('getFilters', (callback)=>{
-            this.getFilters(callback)
-        });
     }
 
     componentWillUnmount() {
-        emitter.removeAllListeners('getFilters');
+        console.log('unmount');
+    }
+
+    componentWillReceiveProps() {
     }
 
     removeFilter = (key) => {
@@ -59,6 +57,14 @@ class FilterBox extends React.Component {
         });
     }
 
+    removeAllFilters = () => {
+        const { form } = this.props;
+        const filters = form.getFieldValue('filters');
+        form.setFieldsValue({
+            filters: [],
+        });
+    }
+
     addFilter = (filtes) => {
         const { form } = this.props;
         const filters = form.getFieldValue('filters');
@@ -151,13 +157,14 @@ class FilterBox extends React.Component {
     /**
      * 获得设定的过滤条件规则
      */
-    getFilters = (callback) => {
-        const { form } = this.props;
+    getFilters = () => {
+        const { form, createFilters, hideFilterBox } = this.props;
         form.validateFields(function(err, values) {
-            if(!err && callback&&(typeof callback == 'function')) {
-                callback(values.filters);
+            if(!err) {
+                createFilters(values.filters);
             }
         })
+        hideFilterBox();
     }
 
     getFilterValueField = (key, type, operator, index) => {
@@ -167,10 +174,10 @@ class FilterBox extends React.Component {
         let filter = filters.filter((f) => {return f.key == key})[0];
         let column = columns.filter((c) => {return c.name == filter.name});
         column = column.length>0?column[0]:{selection:[]};
-        column.selection = column.selection || []
-        if(type == 'string') {
+        column.selection = column.selection || [];
+        if(['index', 'string'].indexOf(type) != -1) {
             field = <Input onBlur={(e) => {this.changeFilterValue(filter, e.target.value, index)}}/>
-        }else if(type == 'number') {
+        }else if(['scale', 'ordinal'].indexOf(type) != -1) {
             field = <InputNumber onBlur={(e) => {this.changeFilterValue(filter, e.target.value, index)}}/>
         }else if(type == 'time') {
             field = <DatePicker onChange={(value) => {this.changeFilterValue(filter, value, index)}}/>
@@ -183,6 +190,8 @@ class FilterBox extends React.Component {
                     return <SelectOption key={i} value={s}>{s}</SelectOption>
                 }) }
             </Select>
+        }else {
+            field = <Input onBlur={(e) => {this.changeFilterValue(filter, e.target.value, index)}}/> 
         }
 
         return field;
@@ -276,24 +285,36 @@ class FilterBox extends React.Component {
     }
 
     render() {
+        const { visibleFilterBox, hideFilterBox, filterData } = this.props;
+
         return (
-            <Form size='small'>
-                {this.getFilterItems()}
-                <Row>
-                    <Col>
-                        <FormItem>
-                            <Button
-                                className='filter-add-button'
-                                type="dashed"
-                                onClick={() => {this.addFilter()}}
-                            >
-                                <Icon type="plus" />
-                                添加
-                            </Button>
-                        </FormItem>
-                    </Col>
-                </Row>
-            </Form>
+            <Modal
+                className='filter-box'
+                title="筛选条件"
+                visible={visibleFilterBox}
+                onOk={this.getFilters}
+                onCancel={hideFilterBox}
+                maskClosable={false}
+                destroyOnClose={true}
+            >
+                <Form size='small'>
+                    {this.getFilterItems()}
+                    <Row>
+                        <Col>
+                            <FormItem>
+                                <Button
+                                    className='filter-add-button'
+                                    type="dashed"
+                                    onClick={() => {this.addFilter()}}
+                                >
+                                    <Icon type="plus" />
+                                    添加
+                                </Button>
+                            </FormItem>
+                        </Col>
+                    </Row>
+                </Form>
+            </Modal>
         );
     }
 }

+ 48 - 1
app/components/chartDesigner/sections/filterOperators.json

@@ -1,4 +1,26 @@
 {
+    "index": [{
+        "value": "contain",
+        "label": "包含"
+    }, {
+        "value": "notContain",
+        "label": "不包含"
+    }, {
+        "value": "startsWith",
+        "label": "开头是"
+    }, {
+        "value": "endsWith",
+        "label": "结尾是"
+    }, {
+        "value": "equals",
+        "label": "等于"
+    }, {
+        "value": "notEquals",
+        "label": "不等于"
+    }, {
+        "value": "null",
+        "label": "为空"
+    }],
     "string": [{
         "value": "contain",
         "label": "包含"
@@ -21,7 +43,7 @@
         "value": "null",
         "label": "为空"
     }],
-    "number": [{
+    "scale": [{
         "value": ">",
         "label": "大于"
     }, {
@@ -78,6 +100,31 @@
         "value": "null",
         "label": "为空"
     }],
+    "ordinal": [{
+        "value": ">",
+        "label": "大于"
+    }, {
+        "value": ">=",
+        "label": "大于等于"
+    }, {
+        "value": "=",
+        "label": "等于"
+    }, {
+        "value": "<=",
+        "label": "小于等于"
+    }, {
+        "value": "<",
+        "label": "小于"
+    }, {
+        "value": "<>",
+        "label": "不等于"
+    }, {
+        "value": "between",
+        "label": "介于"
+    }, {
+        "value": "null",
+        "label": "为空"
+    }],
     "undefined": [{
         "value": "null",
         "label": "无"

+ 25 - 0
app/components/chartDesigner/sections/gauge.json

@@ -0,0 +1,25 @@
+[{
+    "value": "sum",
+    "label": "累计"
+}, {
+    "value": "avg",
+    "label": "平均值"
+}, {
+    "value": "median",
+    "label": "中位数"
+}, {
+    "value": "count",
+    "label": "计数"
+}, {
+    "value": "distinctCount",
+    "label": "不重复计数"
+}, {
+    "value": "max",
+    "label": "最大值"
+}, {
+    "value": "min",
+    "label": "最小值"
+}, {
+    "value": "originalData",
+    "label": "原始值"
+}]

+ 23 - 0
app/components/chartDesigner/sections/granularity.json

@@ -0,0 +1,23 @@
+{
+    "ordinal": null,
+    "categorical": null,
+    "time": [{
+        "value": "year",
+        "label": "年"
+    }, {
+        "value": "halfYear",
+        "label": "半年"
+    }, {
+        "value": "month",
+        "label": "月"
+    }, {
+        "value": "quarter",
+        "label": "季度"
+    }, {
+        "value": "week",
+        "label": "周"
+    }, {
+        "value": "day",
+        "label": "日"
+    }]
+}

+ 4 - 3
app/components/chartDesigner/sections/preparingForm.jsx

@@ -14,11 +14,12 @@ class PreparingForm extends React.Component {
 		return (
 			<Form layout='horizontal'>
 				<FormItem label='分组' {...formItemLayout}>
-					<Select 
+					<Select
 						mode="multiple"
 						labelInValue={true}
+						placeholder='请选择...'
 						onChange={(value) => {
-							props.dispatch({ type: 'chartDesigner/preparing/setGroupBy', groupBy: value});
+							props.dispatch({ type: 'chartDesigner/setModel', name: 'preparing', value: { ...props.chartDesigner.preparing, groupBy: value } });
 						}}
 						value={props.chartDesigner.preparing.groupBy}
 					>
@@ -36,4 +37,4 @@ function mapStateToProps({ present: { chartDesigner } }) {
     return { chartDesigner: chartDesigner }
 }
 
-export default Form.create()(connect(mapStateToProps)(PreparingForm));
+export default connect(mapStateToProps)(PreparingForm);

+ 20 - 29
app/components/chartDesigner/sections/toolbar.jsx

@@ -1,45 +1,47 @@
 import React from 'react';
 import { Tag, Icon, Modal, Button } from 'antd';
 import FilterBox from './filterBox';
-import emitter from '../../../eventManger/ev';
 import { connect } from 'dva';
 import chartDesigner from '../../../models/chartDesigner';
 import './toolbar.less';
 
-class Toolar extends React.Component {
+class Toolbar extends React.Component {
     constructor(props) {
         super(props);
         this.state = {
             filters: props.chartDesigner.filters || [],
-            showFilterBox: false
+            visibleFilterBox: false
         }
     }
 
     filterUsingChange = (e) => {
         const key = e.target.dataset.key;
-        this.props.dispatch({ type: 'chartDesigner/filters/setUsing', key: key});
+        const props = this.props;
+        const chartDesigner = props.chartDesigner;
+        const filters = chartDesigner.filters;
+        props.dispatch({ type: 'chartDesigner/setModel', name: 'filters', value: filters.map( f => {
+            if(f.key == key) {
+                f = { ...f, using: !f.using }
+            }
+            return f;
+        }) });
     }
 
     showFilterBox = (e) => {
         this.setState({
-            showFilterBox: true
+            visibleFilterBox: true
         });
     }
 
     hideFilterBox = (e) => {
         this.setState({
-            showFilterBox: false,
+            visibleFilterBox: false,
         });
     }
 
-    /**
-     * 生成过滤条件
-     */
-    createFilters = () => {
-        emitter.emit('getFilters', function(filters) {
-            this.props.dispatch({ type: 'chartDesigner/filters/createFilters', filters: filters});
-            this.hideFilterBox()
-        }.bind(this));
+    createFilters = (filters) => {
+        this.props.dispatch({ type: 'chartDesigner/setModel', name: 'filters', value: filters });
+        this.hideFilterBox()
     }
 
     /**
@@ -87,7 +89,7 @@ class Toolar extends React.Component {
     render() {
         const filters = this.props.chartDesigner.filters;
         const columns = this.props.chartDesigner.columns;
-        const { showFilterBox } = this.state;
+        const { visibleFilterBox } = this.state;
 
         let tags = filters.map((f, i)=>{
             return {
@@ -116,24 +118,13 @@ class Toolar extends React.Component {
                         onClick={this.showFilterBox}
                         className={`filter-tag filter-tag-add`}
                     >
-                        <Icon type="bars" />
-                        筛选条件管理
+                        <Icon type="setting" />
                     </Tag>
                 </div>
                 <div className='tools'>
                     <Button className='tools-button' size='small'>按钮</Button>
                 </div>
-                <Modal 
-                    className='filter-box'
-                    title="筛选条件管理"
-                    visible={showFilterBox}
-                    onOk={this.createFilters}
-                    onCancel={this.hideFilterBox}
-                    maskClosable={false}
-                    destroyOnClose={true}
-                >
-                    <FilterBox columns={columns} filterData={filters}/>  
-                </Modal>
+                <FilterBox key={Math.random()} columns={columns} filterData={filters} visibleFilterBox={visibleFilterBox} showFilterBox={this.showFilterBox} hideFilterBox={this.hideFilterBox} createFilters={this.createFilters} />  
             </div>
         );
     }
@@ -142,4 +133,4 @@ function mapStateToProps({ present: { chartDesigner } }) {
     return { chartDesigner: chartDesigner }
 }
 
-export default connect(mapStateToProps)(Toolar);
+export default connect(mapStateToProps)(Toolbar);

+ 18 - 0
app/components/layout.jsx

@@ -0,0 +1,18 @@
+import React from 'react';
+import { Layout, Menu, Breadcrumb, Icon, Tabs, Collapse } from 'antd';
+const { Header, Content, Sider } = Layout;
+const CollapsePanel = Collapse.Panel;
+const { TabPane } = Tabs;
+const SubMenu = Menu.SubMenu;
+
+class Layout extends React.Component {
+    render() {
+        return <Layout>
+            <Header>
+            </Header>
+            <Content>
+            </Content>
+        </Layout>
+    }
+}
+export default Layout;

+ 0 - 2
app/eventManger/ev.js

@@ -1,2 +0,0 @@
-import { EventEmitter } from 'events';
-export default new EventEmitter();

+ 36 - 95
app/models/chartDesigner.js

@@ -9,15 +9,15 @@ export default {
         columns: [{
             label: '编号',
             name: 'ID',
-            type: 'number'
+            type: 'index'
         }, {
             label: '姓名',
             name: 'name',
-            type: 'number'
+            type: 'string'
         }, {
             label: '出生日期',
             name: 'BIRTH',
-            type: 'date'
+            type: 'time'
         }, {
             label: '性别',
             name: 'GENDER',
@@ -31,23 +31,23 @@ export default {
         }, {
             label: '入职日期',
             name: 'ENTRYDATE',
-            type: 'date'
+            type: 'time'
         }, {
             label: '当月工作时数',
             name: 'WORKHOURS',
-            type: 'number'
+            type: 'scale'
         }, {
             label: '基本薪资',
             name: 'BASICSALARY',
-            type: 'number'
+            type: 'scale'
         }, {
             label: '绩效薪资',
             name: 'PERFORMANCE',
-            type: 'number'
+            type: 'scale'
         }, {
             label: '实发薪资',
             name: 'SALARY',
-            type: 'number'
+            type: 'scale'
         }],
         allPermission: [
 			{ value: 'owner', name: '创建人' },
@@ -78,7 +78,14 @@ export default {
             groupBy: []
         },
         barConfig: {
-
+            xAxis: {
+                column: {},
+                granularity: {}
+            },
+            yAxis: {
+                column: {},
+                gauge: {}
+            }
         },
         aggregateTable: {
 
@@ -94,82 +101,10 @@ export default {
     },
     reducers: {
         setModel(state, action) {
-            const { model } = action;
-            // action = { model: { baseConfig: { dataSource: { key: 'd1'} } } }
-            function assign(p, c) {
-                for(let k in c) {
-                    if(p.hasOwnProperty(k)) {
-                        if(typeof c[k] == 'object') {
-                            Object.assign({}, p, assign(p, c[k]));
-                        }else {
-                            let obj = p[k];
-                            obj[k] = c[k];
-                            return Object.assign({}, p, obj);
-                        }
-                    }else {
-                        return Object.assign({}, p, c[k]);
-                    }
-                }
-            }
-            let p = {baseConfig: 1};
-            console.log(p);
-            console.log(assign(p, { baseConfig: { dataSource: { key: 'd1'} } } ));
-            return state;
-        },
-        setTitle(state, action) {
-            let newState = Object.assign({}, state, {
-                header: {
-                    label: action.text
-                }
-            });
-            return newState;
-        },
-        /**
-         * 基础设置-数据源
-         */
-        'baseConfig/setDataSource'(state, action) {
-            const baseConfig = state.baseConfig;
-            let newBaseConfig = { ...baseConfig, ...{ dataSource: action.dataSource }};
-            let newState = { ...state, ...{ baseConfig: newBaseConfig }};
-            return newState;
-        },
-        /**
-         * 基础设置-可视化模式
-         */
-        'baseConfig/setViewType'(state, action) {
-            const baseConfig = state.baseConfig;
-            let newBaseConfig = Object.assign({}, baseConfig, {
-                viewType: action.viewType
-            });
-            let newState = Object.assign({}, state, {
-                baseConfig: newBaseConfig
-            });
-            return newState;
-        },
-        /**
-         * 总体统计数据表选项-分析目标
-         */
-        'aggregateTable/setTargetColumn'(state, action) {
-            const aggregateTable = state.aggregateTable;
-            let newAggregateTable = Object.assign({}, aggregateTable, {
-                targetColumn: action.targetColumn
-            });
-            let newState = Object.assign({}, state, {
-                aggregateTable: newAggregateTable
-            });
-            return newState;
-        },
-        /**
-         * 总体统计数据表选项-显示总体数据
-         */
-        'aggregateTable/setStatistics'(state, action) {
-            const aggregateTable = state.aggregateTable;
-            let newAggregateTable = Object.assign({}, aggregateTable, {
-                statistics: action.statistics
-            });
-            let newState = Object.assign({}, state, {
-                aggregateTable: newAggregateTable
-            });
+            const { name, value } = action;
+            let obj = {};
+            obj[name] = value;
+            let newState = Object.assign({}, state, obj);
             return newState;
         },
         /**
@@ -239,7 +174,7 @@ export default {
          * 过滤规则-生成过滤规则
          */
         'filters/createFilters'(state, action) {
-            return { ...state, ...{ filters: action.filters } };
+            return { ...state, filters: action.filters};
         },
         /**
          * 过滤规则-启用/反启用
@@ -260,31 +195,37 @@ export default {
         *['a'](action, { select, call, put }) {
             const chartDesigner = yield select(state => state.present.chartDesigner);
             const { barConfig, preparing } = chartDesigner;
-            const data = yield call(service.fetch, {
+            const res = yield call(service.fetch, {
                 url: URLS.CHART_BAR_OPTION,
                 body: {
                     "tableName": "TEST_BI_DATA",
                     "groups": preparing.groupBy.map(g => g.key),
                     "xAxis": barConfig.xAxis.key,
-                    "yAxis": barConfig.yAxis[0],
-                    "dataType": barConfig.yAxis[1]
+                    "yAxis": barConfig.yAxis.column.value,
+                    "dataType": barConfig.yAxis.gauge.value
                 }
             });
+
             console.log({
                 url: URLS.CHART_BAR_OPTION,
                 body: {
                     "tableName": "TEST_BI_DATA",
                     "groups": preparing.groupBy.map(g => g.key),
                     "xAxis": barConfig.xAxis.key,
-                    "yAxis": barConfig.yAxis[0],
-                    "dataType": barConfig.yAxis[1]
+                    "yAxis": barConfig.yAxis.column.value,
+                    "dataType": barConfig.yAxis.gauge.value
                 }
             })
-            data.viewType = 'bar';
-            if(!data.err) {
-                yield put({ type: 'setOption', chartOption: data });
+            res.viewType = 'bar';
+            res.data.data.xTitle = barConfig.xAxis?barConfig.xAxis.label:null
+            res.data.data.yTitle = barConfig.yAxis?barConfig.yAxis.column.label:null;
+            res.data.data.gauge = barConfig.yAxis?barConfig.yAxis.gauge.label:null;
+            console.log(res);
+            if(!res.err && res.data.code > 0) {
+                yield put({ type: 'setModel', name: 'chartOption', value: res });
             }else {
-                yield put({ type: 'setOption', chartOption: {} });
+                yield put({ type: 'setModel', name: 'chartOption', value: {} });
+                // 弹出错误提示
             }
         },
         *test({payload:todo},{put,call}){

+ 0 - 24
app/models/example.js

@@ -1,24 +0,0 @@
-export default {
-  namespace: 'example',
-
-  state: {},
-
-  subscriptions: {
-    setup({ dispatch, history }) {
-      // eslint-disable-line
-    },
-  },
-
-  effects: {
-    *fetch({ payload }, { call, put }) {
-      // eslint-disable-line
-      yield put({ type: 'save' });
-    },
-  },
-
-  reducers: {
-    save(state, action) {
-      return { ...state, ...action.payload };
-    },
-  },
-};

+ 0 - 11
app/models/preparing.js

@@ -1,11 +0,0 @@
-export default {
-    namespace: 'preparing',
-    state: {
-        groupBy: []
-    },
-    reducers: {
-      set(state, action) {
-        return action.groupBy;
-      }
-    },
-  };

+ 0 - 12
app/models/title.js

@@ -1,12 +0,0 @@
-export default {
-  namespace: 'title',
-  state: {
-    label: '标题'
-  },
-  reducers: {
-    set(state, action) {
-      let newState = Object.assign({}, state, { label: action.text});
-      return newState;
-    }
-  },
-};

BIN
app/resources/images/6165847895E8568AE73E6164F3668271B78151E6C.jpg


BIN
app/resources/images/favicon.ico


+ 0 - 26
app/routes/IndexPage.js

@@ -1,26 +0,0 @@
-import React from 'react';
-import { connect } from 'dva';
-import styles from './IndexPage.css';
-
-function IndexPage() {
-  return (
-    <div className={styles.normal}>
-      <h1 className={styles.title}>Yay! Welcome to dva!</h1>
-      <div className='welcome' />
-      <ul className={styles.list}>
-        <li>
-          To get started, edit <code>src/index.js</code> and save to reload.
-        </li>
-        <li>
-          <a href="https://github.com/dvajs/dva-docs/blob/master/v1/en-us/getting-started.md">
-            Getting Started
-          </a>
-        </li>
-      </ul>
-    </div>
-  );
-}
-
-IndexPage.propTypes = {};
-
-export default connect()(IndexPage);

+ 0 - 73
app/utils/deepAssign.js

@@ -1,73 +0,0 @@
-function isObj(x){	
-	var type = typeof x;
-	return x !== null && (type === 'object' || type === 'function');
-}
-
-var hasOwnProperty = Object.prototype.hasOwnProperty;
-var propIsEnumerable = Object.prototype.propertyIsEnumerable;
-
-function toObject(val) {
-	if (val === null || val === undefined) {
-		throw new TypeError('Cannot convert undefined or null to object');
-	}
-
-	return Object(val);
-}
-
-function assignKey(to, from, key) {
-	var val = from[key];
-
-	if (val === undefined || val === null) {
-		return;
-	}
-
-	if (hasOwnProperty.call(to, key)) {
-		if (to[key] === undefined || to[key] === null) {
-			throw new TypeError('Cannot convert undefined or null to object (' + key + ')');
-		}
-	}
-
-	if (!hasOwnProperty.call(to, key) || !isObj(val)) {
-		to[key] = val;
-	} else {
-		to[key] = assign(Object(to[key]), from[key]);
-	}
-}
-
-function assign(to, from) {
-	if (to === from) {
-		return to;
-	}
-
-	from = Object(from);
-
-	for (var key in from) {
-		if (hasOwnProperty.call(from, key)) {
-			assignKey(to, from, key);
-		}
-	}
-
-	if (Object.getOwnPropertySymbols) {
-		var symbols = Object.getOwnPropertySymbols(from);
-
-		for (var i = 0; i < symbols.length; i++) {
-			if (propIsEnumerable.call(from, symbols[i])) {
-				assignKey(to, from, symbols[i]);
-			}
-		}
-	}
-
-	return to;
-}
-
-function deepAssign(target) {
-	target = toObject(target);
-
-	for (var s = 1; s < arguments.length; s++) {
-		assign(target, arguments[s]);
-	}
-
-	return target;
-};
-
-exports.module = deepAssign;

+ 0 - 1
package.json

@@ -9,7 +9,6 @@
     "dva": "^2.3.1",
     "echarts": "^4.1.0",
     "echarts-for-react": "^2.0.12-beta.0",
-    "events": "^3.0.0",
     "moment": "^2.19.3",
     "prop-types": "^15.6.2",
     "react": "^16.2.0",