Browse Source

钻取设置组件列限制校验逻辑完善

zhuth 6 years ago
parent
commit
da0f6aaa96

+ 7 - 3
src/components/chartDesigner/sections/barConfigForm.jsx

@@ -20,7 +20,11 @@ const BarConfigForm = ({ autoRefresh, chartDesigner, dispatch }) => {
 			<FormItem label='横轴' {...formItemLayout}>
 				<XAxisItem value={barConfig.xAxis} options={columns.filter(c =>['ordinal', 'categorical', 'time'].indexOf(c.type) > -1)}
 					onChange={({ column, granularity }) => {
-						dispatch({ type: 'chartDesigner/changeField', name: 'barConfig', value: { ...barConfig, xAxis: { column, granularity }, drillList: [] }, autoRefresh });
+						dispatch({ type: 'chartDesigner/changeField', name: 'barConfig', value: {
+							...barConfig,
+							xAxis: { column, granularity },
+							drillList: [{ column, granularity }] 
+						}, autoRefresh });
 					}}
 				/>
 			</FormItem>
@@ -101,7 +105,7 @@ const BarConfigForm = ({ autoRefresh, chartDesigner, dispatch }) => {
 					checked={!!barConfig.drillable}
 					onChange={e => {
 						let checked = e.target.checked;
-						let drillList = [];
+						let drillList = [{ column: barConfig.xAxis.column, granularity: barConfig.xAxis.granularity }];
 						if(barConfig.xAxis.column.type === 'time') { // 如果x轴字段是时间类型,自动生成其维度钻取层级
 							const granularitys = GRANULARITY['time'];
 							let idx = granularitys.findIndex(g => g.value === barConfig.xAxis.granularity.value);
@@ -119,7 +123,7 @@ const BarConfigForm = ({ autoRefresh, chartDesigner, dispatch }) => {
 			{barConfig.xAxis.column.value && barConfig.drillable && <FormItem label='钻取层级' {...formItemLayout}>
 				<DrillList
 					// 可选钻取字段包括时间、类别类型,且当x轴选择的是时间类型时允许重复作为钻取字段(之后会限制年月周等维度的选择)
-					list={columns.filter(c => (barConfig.xAxis.column.type === 'time' ? true : c.name !== barConfig.xAxis.column.value) && ['categorical', 'time'].indexOf(c.type) > -1)}
+					list={columns.filter(c => ['categorical', 'time'].indexOf(c.type) > -1)}
 					value={barConfig.drillList || []}
 					onChange={list => {
 						dispatch({ type: 'chartDesigner/changeField', name: 'barConfig', value: { ...barConfig, drillList: list }, autoRefresh });

+ 11 - 3
src/components/chartDesigner/sections/drillList.jsx

@@ -7,16 +7,24 @@ const DrillList = ({ className, list, value, onChange }) => {
     let newValue = value.map(v => v);
     return <div className={`drill-list ${className || ''}`}>
         {value.map((v, i) => {
-            const options = list.filter(l => !value.find(vi => vi.column.value !== v.column.value && vi.column.value === l.name));
+            const options = list.filter(l => l.type === 'time' || !value.find(vi => vi.column.value !== v.column.value && vi.column.value === l.name));
             return <Row key={i}>
                 <Col span={20}>
-                    <XAxisItem value={v} options={options} onChange={v => {
+                    <XAxisItem value={v} disabled={i === 0} options={options} onChange={v => {
+                        let idx = value.findIndex(t => t.column.value === v.column.value && t.granularity.value === v.granularity.value);
+                        if(idx > -1) {
+                            message.error('不可添加重复层级');
+                            return;
+                        }
                         newValue[i] = v;
                         onChange(newValue);
                     }}/>
                 </Col>
                 <Col span={4} style={{ textAlign: 'center' }}>
-                    <Icon type='delete' style={{ cursor: 'pointer' }} onClick={() => {
+                    <Icon type='delete' style={ i === 0 ? { cursor: 'not-allowed', color: '#97a5b1' } : { cursor: 'pointer' }} onClick={() => {
+                        if(i === 0) {
+                            return;
+                        }
                         newValue.splice(i, 1);
                         onChange(newValue);
                     }}/>

+ 63 - 72
src/components/chartDesigner/sections/xAxisItem.jsx

@@ -2,78 +2,69 @@ import React from 'react';
 import { Cascader } from 'antd';
 import GRANULARITY from './granularity.json';
 
-class XAxisItem extends React.PureComponent {
-    constructor(props) {
-        super(props);
-        this.state = {
-
-        }
-    }
-
-    render() {
-        const { value: _propsValue, options, onChange } = this.props;
-        return <Cascader
-            value={[_propsValue.column.value, _propsValue.granularity.value]}
-            allowClear={true}
-            showSearch={{
-                filter: (inputValue, path) => {
-                    let p0 = path[0].label.toLowerCase();
-                    let v = inputValue.toLowerCase();
-                    return p0.indexOf(v) !== -1;
-                },
-                sort: (a, b, inputValue) => {
-                    return a[0].label.localeCompare(b[0].label,"zh");
-                },
-                render: (inputValue, path) => {
-                    const reg = new RegExp('([+ \\- & | ! ( ) { } \\[ \\] ^ \" ~ * ? : ( ) \/])', 'g'); // 需要转义的字符
-                    let v = inputValue.replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1'); // 添加转义符号
-                    let label0 = (path[0].label.split(new RegExp(`(${v})`, 'i')).map((fragment, i) => {
-                        return (
-                            fragment.toLowerCase().replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1') === v.toLowerCase() ?
-                            <span key={i} style={{fontWeight: 'bold', color: 'red'}} className="highlight">{fragment}</span> :
-                            fragment
-                        )
-                    }))
-                    return <div>{label0}{path[1] ? '>' + path[1].label : ''}</div>
-                }
-            }}
-            options={options.map((c, i)=>{
-                return {
-                    type: c.type,
-                    value: c.name,
-                    label: c.label,
-                    children: GRANULARITY[c.type]
-                }
-            })}
-            onChange={(value, items) => {
-                let column = {};
-                let granularity = {};
-                if(items.length > 0) {
-                    column = { type: items[0].type, value: items[0].value, label: items[0].label };
-                }
-                if(items.length > 1) {
-                    granularity = { value: items[1].value, label: items[1].label };
-                }
-                onChange({ 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 = '请选择...';
+const XAxisItem = ({ value: _propsValue, disabled, options, onChange }) => {
+    return <Cascader
+        value={[_propsValue.column.value, _propsValue.granularity.value]}
+        disabled={disabled}
+        allowClear={true}
+        showSearch={{
+            filter: (inputValue, path) => {
+                let p0 = path[0].label.toLowerCase();
+                let v = inputValue.toLowerCase();
+                return p0.indexOf(v) !== -1;
+            },
+            sort: (a, b, inputValue) => {
+                return a[0].label.localeCompare(b[0].label,"zh");
+            },
+            render: (inputValue, path) => {
+                const reg = new RegExp('([+ \\- & | ! ( ) { } \\[ \\] ^ \" ~ * ? : ( ) \/])', 'g'); // 需要转义的字符
+                let v = inputValue.replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1'); // 添加转义符号
+                let label0 = (path[0].label.split(new RegExp(`(${v})`, 'i')).map((fragment, i) => {
+                    return (
+                        fragment.toLowerCase().replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1') === v.toLowerCase() ?
+                        <span key={i} style={{fontWeight: 'bold', color: 'red'}} className="highlight">{fragment}</span> :
+                        fragment
+                    )
+                }))
+                return <div>{label0}{path[1] ? '>' + path[1].label : ''}</div>
+            }
+        }}
+        options={options.map((c, i)=>{
+            return {
+                type: c.type,
+                value: c.name,
+                label: c.label,
+                children: GRANULARITY[c.type]
+            }
+        })}
+        onChange={(value, items) => {
+            let column = {};
+            let granularity = {};
+            if(items.length > 0) {
+                column = { type: items[0].type, value: items[0].value, label: items[0].label };
+            }
+            if(items.length > 1) {
+                granularity = { value: items[1].value, label: items[1].label };
+            }
+            onChange({ 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] + ')';
                 }
-                return <div className={className}>{text}</div>;
-            }}
-        >
-        </Cascader> 
-    }
-}
+            }else {
+                className += ' empty-label';
+                text = '请选择...';
+            }
+            return <div className={className}>{text}</div>;
+        }}
+    >
+    </Cascader> 
+}; 
 
 export default XAxisItem;