Browse Source

图表界面条件筛选栏超出一行的条件放入“更多”弹出展示/图表元素增加、移除、改变高度后自动触发页面刷新

zhuth 6 years ago
parent
commit
453de63d70

+ 0 - 6
src/components/chartDesigner/charts/echartsView.jsx

@@ -8,12 +8,6 @@ import { Icon,message } from 'antd';
 import moment from 'moment';
 moment.locale('zh-cn');
 moment.suppressDeprecationWarnings = true;
-const isMobile = function() {
-    if ((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i)))
-        return true;
-    else
-        return false;
-};
 class EchartsView extends Component {
     render() { 
         const { chartOption, inDashBoard, item } = this.props;

+ 6 - 0
src/components/common/filterBox/filter.less

@@ -9,6 +9,12 @@
             min-width: 100px;
         }
     }
+    &.vertical {
+        flex-direction: column;
+        .ant-form-item-control, .ant-form-item-children, .ant-select {
+            width: 100%;
+        }
+    }
 }
 
 .cus-time-picker {

+ 2 - 2
src/components/common/filterBox/filter2.jsx

@@ -19,10 +19,10 @@ class Filter extends React.Component {
     }
 
     generatFilter = () => {
-        const { filter } = this.props;
+        const { filter, vertical } = this.props;
         const { label, type, operator, operatorLabel } = filter;
         
-        return <div className='filter'>
+        return <div className={`filter ${vertical ? 'vertical' : ''}`}>
             <span className='filter-name'>{label + ' ' + operatorLabel + ' : '}</span>
             <FormItem className='filter-value filter-value1'>
                 { this.generateValueItem(filter, 1) }

+ 4 - 1
src/components/dashboardDesigner/chooseChartBox.jsx

@@ -69,10 +69,13 @@ class ChooseChartBox extends React.Component {
         if(selectedRecords.length > 0) {
             dispatch({ type: 'dashboardDesigner/addCharts', charts: selectedRecords });
             hideBox();
-            setTimeout(() => {
+            window.setTimeout(() => {
                 // 滚动到最底部
                 let viewScrollContent = document.querySelector('.viewlayout');
                 viewScrollContent.scrollTo && viewScrollContent.scrollTo(0, viewScrollContent.scrollHeight - viewScrollContent.clientHeight);
+                var e = document.createEvent("Event");
+                e.initEvent("resize", true, true);
+                window.dispatchEvent(e);
             }, 500);
         }else {
             message.warning('请选择需要添加的图表');

+ 4 - 0
src/components/dashboardDesigner/configSider.jsx

@@ -67,6 +67,10 @@ class ConfigSider extends React.Component {
                     // 滚动到最底部
                     let viewScrollContent = document.querySelector('.viewlayout');
                     viewScrollContent.scrollTo && viewScrollContent.scrollTo(0, viewScrollContent.scrollHeight - viewScrollContent.clientHeight);
+                    
+                    var e = document.createEvent("Event");
+                    e.initEvent("resize", true, true);
+                    window.dispatchEvent(e);
                 }, 500);
             }}>
                 <Icon type='book'/>

+ 54 - 25
src/components/dashboardDesigner/content.jsx

@@ -1,12 +1,21 @@
-import React from 'react'
-import { Layout, Tag, Icon } from 'antd'
-import { connect } from 'dva'
-import ViewLayout from './viewLayout'
-import FilterBox from '../common/filterBox/filterBox2'
-import Filter from '../common/filterBox/filter2'
-import ConfigSider from './configSider'
+import React, { Fragment } from 'react';
+import { Layout, Tag, Icon } from 'antd';
+import { connect } from 'dva';
+import ViewLayout from './viewLayout';
+import FilterBox from '../common/filterBox/filterBox2';
+import Filter from '../common/filterBox/filter2';
+import ConfigSider from './configSider';
+import FilterList from './filterList'
 
-const { Header, Content, Sider } = Layout
+const { Header, Content, Sider } = Layout;
+
+const isMobile = function() {
+    if ((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i)))
+        return true;
+    else
+        return false;
+};
+const esMobile = isMobile();
 
 class DashboardDesignerContent extends React.Component {
     constructor(props) {
@@ -18,17 +27,13 @@ class DashboardDesignerContent extends React.Component {
                 height: 0,
             },
             visibleFilterBox: false,
-            closeFilters: false,
+            visibleFilterList: false,
+            overFilters: false,
         };
         this.contentRef=React.createRef();
     }
 
     componentDidMount() {
-        const { dashboardDesigner } = this.props;
-        const { filters } = dashboardDesigner;
-        this.setState({
-            closeFilters: filters.length > 6
-        });
         this.refreshContentSize();
         window.addEventListener("resize", this.refreshContentSize);
     }
@@ -54,6 +59,12 @@ class DashboardDesignerContent extends React.Component {
      */
     refreshContentSize = () => {
         let viewLayoutEl = this.contentRef.current;
+        let header = viewLayoutEl.getElementsByClassName('ant-layout-header')[0];
+        let overFilters = false;
+        if(!!header) {
+            let filterBar = header.getElementsByClassName('filters')[0].getElementsByClassName('content')[0];
+            overFilters = filterBar.scrollHeight > filterBar.offsetHeight;
+        }
         let viewContentEl = viewLayoutEl.getElementsByClassName('dashboard-viewcontent')[0];
         let _scroll = viewContentEl.scrollHeight > viewContentEl.clientHeight;
         let padding = 0;
@@ -63,7 +74,8 @@ class DashboardDesignerContent extends React.Component {
             contentSize: {
                 width,
                 height
-            }
+            },
+            overFilters
         });
     }
 
@@ -94,7 +106,7 @@ class DashboardDesignerContent extends React.Component {
     render() {
         const { dashboardDesigner, isOwner, isShareView, isShareKeyView, isViewMode } = this.props;
         const { dataSources, editMode, filters, relationColumns } = dashboardDesigner;
-        const { visibleFilterBox, contentSize, closeFilters } = this.state;
+        const { visibleFilterBox, visibleFilterList, contentSize, overFilters } = this.state;
 
         return <Layout className='content'>
             <Content className={`dashboard-content${(isShareView || isShareKeyView || isViewMode) ? ' nomargin' : ''}`}>
@@ -103,12 +115,12 @@ class DashboardDesignerContent extends React.Component {
                         <ConfigSider/>
                     </Sider>}
                     {/**
-                        这里直接用main标签而不用antd的Header组件是为了让ref能够定位到对应的dom元素
+                        这里直接用main标签而不用antd组件是为了让ref能够定位到对应的dom元素
                     */}
                     <main ref={this.contentRef} className='viewlayout ant-layout-content'>
                         {(editMode || (filters && filters.length > 0) )&& <Header>
                             {/* <div className='toggle'><Icon type="caret-up" /></div> */}
-                            <div className={`filters${closeFilters ? ' closed': ''}`}>
+                            <div className={`filters`}>
                                 <div className='content'>
                                     {isOwner && editMode && !isShareView && !isShareKeyView && !isViewMode && <Tag
                                         onClick={this.showFilterBox}
@@ -124,17 +136,34 @@ class DashboardDesignerContent extends React.Component {
                                         />
                                     ))}
                                 </div>
-                                <div className='right' style={{ display: filters.length > 0 ? 'block' : 'none' }}>
-                                    <Icon title={closeFilters ? '展开' : '收起'} type={closeFilters ? 'caret-up' : 'caret-down'} onClick={() => {
+                                {overFilters && <div className='right' style={{ display: filters.length > 0 ? 'block' : 'none' }}>
+                                    <Fragment>
+                                        <span style={{ cursor: 'pointer' }} onClick={() => {
+                                            this.setState({
+                                                visibleFilterList: true
+                                            });
+                                        }}>{esMobile ? '' : '更多'}</span>
+                                        <Icon title={'更多'} type={'ellipsis'} onClick={() => {
+                                            this.setState({
+                                                visibleFilterList: true
+                                            });
+                                        }}/>
+                                    </Fragment>
+                                </div>}
+                                {visibleFilterList && <FilterList
+                                    visible={visibleFilterList}
+                                    onCancel={() => {
                                         this.setState({
-                                            closeFilters: !closeFilters
-                                        });
-                                    }}/>
-                                </div>
+                                            visibleFilterList: false
+                                        })
+                                    }}
+                                    filters={filters}
+                                    changeFilterValue={this.changeFilterValue}
+                                />}
                             </div>
                             {visibleFilterBox && <FilterBox key={Math.random()} dataSources={dataSources} relationColumns={relationColumns} filterData={filters} visibleFilterBox={visibleFilterBox} showFilterBox={this.showFilterBox} hideFilterBox={this.hideFilterBox} createFilters={this.createFilters} />}
                         </Header>}
-                        <ViewLayout isOwner={isOwner} isShareView={isShareView} isShareKeyView={isShareKeyView} isViewMode={isViewMode} contentSize={contentSize} editMode={editMode}/>
+                        <ViewLayout isOwner={isOwner} isShareView={isShareView} isShareKeyView={isShareKeyView} isViewMode={isViewMode} contentSize={contentSize} editMode={editMode} esMobile={esMobile}/>
                     </main>
                 </Layout>
             </Content>

+ 24 - 0
src/components/dashboardDesigner/filterList.jsx

@@ -0,0 +1,24 @@
+import React from 'react';
+import { Modal } from 'antd';
+import Filter from '../common/filterBox/filter2';
+import './filterList.less'
+
+const FilterList = ({ visible, onCancel, filters, changeFilterValue }) => {
+    return <Modal
+        className='filterlist'
+        footer={null}
+        visible={visible}
+        onCancel={onCancel}
+        maskClosable={true}
+        destroyOnClose={true}
+    >
+        {filters.map(f => <Filter
+            vertical={true}
+            key={f.key}
+            filter={f}
+            changeFilterValue={changeFilterValue}
+        />)}
+    </Modal>
+}
+
+export default FilterList;

+ 3 - 0
src/components/dashboardDesigner/filterList.less

@@ -0,0 +1,3 @@
+.filterlist {
+    top: 5%;
+}

+ 5 - 7
src/components/dashboardDesigner/layout.less

@@ -71,16 +71,14 @@
                 border: none;
                 .filters {
                     display: flex;
-                    border: none;
-                    background: #FCFCFC;
-                    width: 100%;
                     justify-content: space-between;
+                    height: 40px;
+                    width: 100%;
+                    background: #FCFCFC;
                     padding-left: 8px;
+                    border: none;
+                    overflow: hidden;
                     transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
-                    &.closed {
-                        height: 39px;
-                        overflow: hidden;
-                    }
                     .content {
                         flex: 1;
                         display: flex;

+ 10 - 11
src/components/dashboardDesigner/viewLayout.jsx

@@ -7,13 +7,6 @@ import EmptyContent from '../common/emptyContent/index'
 import DataPreview from '../common/dataPreview/dataPreview'
 import ViewLayoutItem from './viewLayoutItem';
 
-const isMobile = function() {
-    if ((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i)))
-        return true;
-    else
-        return false;
-};
-const esMobile = isMobile();
 class ViewLayout extends React.PureComponent {
     constructor(props) {
         super(props);
@@ -42,7 +35,7 @@ class ViewLayout extends React.PureComponent {
         });
     }
 
-    createElement = (item, isPreview, reload, contentSize) => {
+    createElement = (item, isPreview, reload, contentSize, esMobile) => {
         const { code, layout } = item;
         return <div key={code} data-grid={esMobile ? { x:0, y:50, w:12, h:8, minW: 12, maxW:12, minH:8, maxH:8 } : layout} style={{ height: '100%' }}>
             <ViewLayoutItem
@@ -61,6 +54,12 @@ class ViewLayout extends React.PureComponent {
         const { dispatch } = this.props;
         if(!(layout.length === 1 && layout[0].i === 'default-chartview')) {
             dispatch({ type: 'dashboardDesigner/changeLayout', layout });
+            window.clearTimeout(this.layoutChangeKey);
+            this.layoutChangeKey = window.setTimeout(() => {
+                var e = document.createEvent("Event");
+                e.initEvent("resize", true, true);
+                window.dispatchEvent(e);
+            }, 500);
         }
     }
 
@@ -105,11 +104,11 @@ class ViewLayout extends React.PureComponent {
     }
 
     render() {
-        const { dashboardDesigner, contentSize, dispatch } = this.props;
+        const { dashboardDesigner, contentSize, esMobile, dispatch } = this.props;
         const { editingKey } = this.state;
         const { editMode, minLayoutHeight, layoutMargin, theme: themeName } = dashboardDesigner;
         const { visiblePreviewBox, previewItem } = this.state;
-        const children = dashboardDesigner.items.map((item) => this.createElement(item, false, !item.chartOption, contentSize));
+        const children = dashboardDesigner.items.map((item) => this.createElement(item, false, !item.chartOption, contentSize, esMobile));
         return (<div className={`dashboard-viewcontent ${themeName}`} ref={node => this.viewContentRef = node}>
             <ReactGridLayout
                 width={ contentSize.width }
@@ -148,7 +147,7 @@ class ViewLayout extends React.PureComponent {
                 keyboard={true}
                 maskClosable={true}
                 >
-                {!!previewItem && this.createElement(dashboardDesigner.items.find(item => item.code === previewItem.code), true, false, {width: document.body.offsetWidth-36*2, height:document.body.offsetHeight - 40})}
+                {!!previewItem && this.createElement(dashboardDesigner.items.find(item => item.code === previewItem.code), true, false, {width: document.body.offsetWidth-36*2, height:document.body.offsetHeight - 40}, esMobile)}
             </Modal>}
         </div>);
     }

+ 6 - 1
src/components/dashboardDesigner/viewLayoutItem.jsx

@@ -86,11 +86,16 @@ class ViewLayoutItem extends React.Component {
                         }}/>}
                         {!isPreview && editMode && <Icon className={iconCls} type='delete' onClick={() => {
                             dispatch({ type: 'dashboardDesigner/deleteItem', item });
+                            window.setTimeout(() => {
+                                var e = document.createEvent("Event");
+                                e.initEvent("resize", true, true);
+                                window.dispatchEvent(e);
+                            }, 500);
                         }} />}
                         {isPreview && <Icon className={iconCls} type="close" onClick={hidePreviewBox}/>}
                     </div>
                 </div>
-                <ChartView chartRef={`chartRef-${dashboardDesignerCode}-${code}`} minLayoutHeight={minLayoutHeight} editMode={isPreview ? false : editMode} item={{...item}} reload={reload} contentSize={contentSize}/>
+                <ChartView chartRef={`chartRef-${dashboardDesignerCode}-${code}`} minLayoutHeight={minLayoutHeight} editMode={isPreview ? false : editMode} item={{...item}} reload={reload} contentSize={contentSize} esMobile={esMobile}/>
             </div>
         )
     }