Pārlūkot izejas kodu

重设图表列表组件结构,多数据渲染交互效率优化

zhuth 6 gadi atpakaļ
vecāks
revīzija
65e4fba56e

+ 54 - 71
src/components/chart/chartCard.jsx

@@ -1,80 +1,63 @@
 import React from 'react';
 import { connect } from 'dva';
-import { Card, Row, Col, Dropdown, Icon } from 'antd';
+import { Icon, Dropdown } from 'antd';
 import moment from 'moment';
 import Thumbnail from './thumbnail';
-const CardGrid = Card.Grid;
-const reg = new RegExp('([+ \\- & | ! ( ) { } \\[ \\] ^ \" ~ * ? : ( ) \/])', 'g'); // 需要转义的字符
+import './chartCard.less';
 
-class ChartCard extends React.Component {
-    render() {
-        const { key, chart, onCardClick, filterItem, filterLabel, generateOperationMenu, dispatch } = this.props;
+const reg = new RegExp('([+ \\- & | ! ( ) { } \\[ \\] ^ \" ~ * ? : ( ) \/])', 'g'); // 需要转义的字符
 
-        return <CardGrid
-            className={`chart-card ${chart.visible ? `visible` : `hidden`}`}
-            key={key}
-            onClick={() => {
-                onCardClick(chart);
-            }}
-        >
-            <Card
-                bordered={false}
-                title={
-                    <Row type='flex' justify='space-between' title={chart.name}>
-                        <Col className='label' style={{ overflow: 'hidden', textOverflow: 'ellipsis', padding: '0 16px' }} >
-                            { (filterItem.name === 'name' && filterLabel) ?
-                                ((chart.name || '').split(new RegExp(`(${filterLabel})`, 'i')).map((fragment, i) => {
-                                    return (
-                                        fragment.toLowerCase().replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1') === filterLabel.toLowerCase() ?
-                                        <span key={i} style={{fontWeight: 'bold', color: 'red'}} className="highlight">{fragment}</span> :
-                                        fragment
-                                    )
-                                }
-                                )) : chart.name
-                            }
-                        </Col>
-                    </Row>
-                }
-                cover={
-                    <Col className='cover-body'>
-                        <Row className='thumb' onClick={chart.access && chart.database ? () => {
-                            dispatch({ type: 'chartDesigner/reset' });
-                            dispatch({ type: 'main/redirect', path: '/chart/' + chart.code });
-                            dispatch({ type: 'recent/addRecentRecord', tarId: chart.code, recordType: 0});
-                        } : () => {}}>
-                            {!chart.database ? <div className='deny-body'>
-                                <div className='deny-tip'>数据源丢失</div>
-                            </div> : (!chart.access ? <div className='deny-body'>
-                                <div className='deny-tip'>无数据权限</div>
-                            </div> : null)}
-                            <Thumbnail key={chart.code} style={{ opacity: (chart.access && chart.database) ? 1 : 0.3 }} type={chart.type} code={chart.code} thumbnail={chart.thumbnail}/>
-                        </Row>
-                        <Row className='footer' type='flex' justify='end' align='bottom'>
-                            <Col style={{ textAlign: 'left', lineHeight: '28px' }} span={21}>
-                                <Row>{
-                                    (filterItem.name === 'creatorName' && filterLabel) ?
-                                    ((chart.creatorName || '').split(new RegExp(`(${filterLabel})`, 'i')).map((fragment, i) => {
-                                        return (
-                                            fragment.toLowerCase().replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1') === filterLabel.toLowerCase() ?
-                                            <span key={i} style={{fontWeight: 'bold', color: 'red'}} className="highlight">{fragment}</span> :
-                                            fragment
-                                        )
-                                    }
-                                    )) : chart.creatorName
-                                } {moment(chart.createTime).format('YYYY-MM-DD')}</Row>
-                            </Col>
-                            <Col span={3} style={{ textAlign: 'right' }}>
-                                <Dropdown overlay={generateOperationMenu()} trigger={['click']}>
-                                    <Icon style={{ fontSize: '24px' }} type="ellipsis" theme="outlined" />
-                                </Dropdown>
-                            </Col>
-                        </Row>
-                    </Col>
+const ChartCard = ({ key, chart, onCardClick, filterItem, filterLabel, generateOperationMenu, dispatch }) => (
+    <div className={`chart-card ${chart.visible ? `visible` : `hidden`}`} onClick={() => { onCardClick.call(this, chart) }}>
+        <div className='header'>
+            <div className='label' title={chart.name}>
+                { (filterItem.name === 'name' && filterLabel) ?
+                    ((chart.name || '').split(new RegExp(`(${filterLabel})`, 'i')).map((fragment, i) => {
+                        return (
+                            fragment.toLowerCase().replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1') === filterLabel.toLowerCase() ?
+                            <span key={i} style={{fontWeight: 'bold', color: 'red'}} className="highlight">{fragment}</span> :
+                            fragment
+                        )
+                    }
+                    )) : chart.name
                 }
-            >
-            </Card>
-        </CardGrid>
-    }
-}
+            </div>
+        </div>
+        <div className='body'>
+            <div className='thumb' onClick={chart.access && chart.database ? () => {
+                dispatch({ type: 'chartDesigner/reset' });
+                dispatch({ type: 'main/redirect', path: '/chart/' + chart.code });
+                dispatch({ type: 'recent/addRecentRecord', tarId: chart.code, recordType: 0});
+            } : () => {}}>
+                {!chart.database ? <div className='deny-body'>
+                    <div className='deny-tip'>数据源丢失</div>
+                </div> : (!chart.access ? <div className='deny-body'>
+                    <div className='deny-tip'>无数据权限</div>
+                </div> : null)}
+                <Thumbnail key={chart.code} style={{ opacity: (chart.access && chart.database) ? 1 : 0.3 }} type={chart.type} code={chart.code} thumbnail={chart.thumbnail}/>
+            </div>
+        </div>
+        <div className='footer'>
+            <div  className='footer-left ant-col-21'>
+                <div>{
+                    (filterItem.name === 'creatorName' && filterLabel) ?
+                    ((chart.creatorName || '').split(new RegExp(`(${filterLabel})`, 'i')).map((fragment, i) => {
+                        return (
+                            fragment.toLowerCase().replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1') === filterLabel.toLowerCase() ?
+                            <span key={i} style={{fontWeight: 'bold', color: 'red'}} className="highlight">{fragment}</span> :
+                            fragment
+                        )
+                    }
+                    )) : chart.creatorName
+                } {moment(chart.createTime).format('YYYY-MM-DD')}</div>
+            </div>
+            <div className='footer-right ant-col-3'>
+                <Dropdown overlay={generateOperationMenu()} trigger={['click']}>
+                    <Icon style={{ fontSize: '24px' }} type="ellipsis" theme="outlined" />
+                </Dropdown>
+            </div>
+        </div>
+    </div>
+)
 
 export default connect()(ChartCard);

+ 77 - 0
src/components/chart/chartCard.less

@@ -0,0 +1,77 @@
+.chart-card {
+    width: 207px;
+    text-align: center;
+    margin: 8px;
+    padding: 0;
+    box-shadow: none;
+    border-radius: @border-radius-base;
+    transition: none;
+    box-sizing: border-box;
+    position: relative;
+    background: #fff;
+    &:hover {
+        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
+    }
+    &.hidden {
+        display: none;
+    }
+    &>.header {
+        min-height: 20px;
+        cursor: default;
+        padding: 6px 0;
+        background: #D6EEFE;
+        >.label {
+            overflow: hidden;
+            text-overflow: ellipsis;
+            padding: 0 16px;
+            width: 100%;
+            font-size: 14px;
+            color: #2c82be;
+            text-align: center;
+        }
+    }
+    &>.body {
+        padding: 10px;
+        .thumb {
+            height: 132px;
+            .deny-body {
+                height: 100%;
+                width: 100%;
+                display: flex;
+                position: absolute;
+                text-align: center;
+                justify-content: center;
+                flex-direction: column;
+                z-index: 1;
+                .deny-tip {
+                    height: 40px;
+                    line-height: 40px;
+                    background: rgba(218, 218, 218, 0.5);
+                    border: 2px solid #aaaaaa;
+                    font-weight: bold;
+                }
+            }
+            cursor: pointer;
+            .chart-thumbnail {
+                height: 132px;
+            }
+        }
+    }
+    .footer {
+        padding: 0 10px 10px 10px;
+        display: flex;
+        align-items: flex-end;
+        flex-flow: row wrap;
+        cursor: default;
+        &-left {
+            text-align: left;
+            line-height: 28px;
+        }
+        &-right {
+            text-align: right;
+            .anticon {
+                cursor: pointer;
+            }
+        }
+    }
+}

+ 2 - 116
src/components/chart/list.less

@@ -71,122 +71,8 @@
                     content: none;
                 }
                 &>.chart-body {
-                    .chart-card {
-                        width: 207px;
-                        text-align: center;
-                        margin: 8px;
-                        padding: 0;
-                        box-shadow: none;
-                        border-radius: @border-radius-base;
-                        &:hover {
-                            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
-                        }
-                        &.hidden {
-                            display: none;
-                        }
-                        &>.ant-card {
-                            &>.ant-card-head {
-                                min-height: 20px;
-                                cursor: default;
-                                padding: 0;
-                                &>.ant-card-head-wrapper {
-                                    &>.ant-card-head-title {
-                                        font-size: 14px;
-                                        padding: 6px 0;
-                                        .ant-row-flex {
-                                            flex: 1;
-                                            .label {
-                                                width: 100%;
-                                                text-align: center;
-                                            }
-                                        }
-                                        .anticon {
-                                            cursor: pointer;
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                        .ant-card-cover {
-                            .cover-body {
-                                padding: 10px;
-                                .thumb {
-                                    height: 132px;
-                                    .deny-body {
-                                        height: 100%;
-                                        width: 100%;
-                                        display: flex;
-                                        position: absolute;
-                                        text-align: center;
-                                        justify-content: center;
-                                        flex-direction: column;
-                                        z-index: 1;
-                                        .deny-tip {
-                                            height: 40px;
-                                            line-height: 40px;
-                                            background: rgba(218, 218, 218, 0.5);
-                                            border: 2px solid #aaaaaa;
-                                            font-weight: bold;
-                                        }
-                                    }
-                                    cursor: pointer;
-                                    canvas {
-                                        cursor: pointer;
-                                    }
-                                    .chart-thumbnail {
-                                        width: 100%;
-                                        height: 100%;
-
-                                        &-table {
-                                            background-image: url(../../../static/images/thumbnail-table.png);
-                                            background-position: center;
-                                            background-size: contain;
-                                            background-repeat: no-repeat;
-                                            cursor: pointer;
-                                        }
-                                        &-aggregateTable {
-                                            background-image: url(../../../static/images/thumbnail-aggregateTable.png);
-                                            background-position: center;
-                                            background-size: contain;
-                                            background-repeat: no-repeat;
-                                            cursor: pointer;
-                                        }
-                                        &-indicator {
-                                            background-image: url(../../../static/images/thumbnail-indicator.png);
-                                            background-position: center;
-                                            background-size: contain;
-                                            background-repeat: no-repeat;
-                                            cursor: pointer;
-                                        }
-                                        &-empty {
-                                            background-image: url(../../../static/images/thumbnail-default.png);
-                                            background-position: center;
-                                            background-size: contain;
-                                            background-repeat: no-repeat;
-                                            cursor: pointer;
-                                            opacity: .3;
-                                        }
-                                    }
-                                }
-                                .desc {
-                                    text-align: left;
-                                    height: 41px;
-                                }
-                                .footer {
-                                    margin-top: 6px;
-                                }
-                            }
-                            .ant-row-flex-bottom {
-                                cursor: default;
-                                .anticon {
-                                    cursor: pointer;
-                                }
-                            }
-                        }
-                        .ant-card-body {
-                            padding: 0;
-                        }
-                    }
+                    display: flex;
+                    flex-wrap: wrap;
                 }
             }
         }

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

@@ -1,4 +1,6 @@
-import React from 'react'
+import React from 'react';
+import './thumbnail.less';
+
 const Thumbnail = ({ style, type, code, thumbnail }) => {
     let children;
     

+ 34 - 0
src/components/chart/thumbnail.less

@@ -0,0 +1,34 @@
+.chart-thumbnail {
+    width: 100%;
+    height: 100%;
+
+    &-table {
+        background-image: url(../../../static/images/thumbnail-table.png);
+        background-position: center;
+        background-size: contain;
+        background-repeat: no-repeat;
+        cursor: pointer;
+    }
+    &-aggregateTable {
+        background-image: url(../../../static/images/thumbnail-aggregateTable.png);
+        background-position: center;
+        background-size: contain;
+        background-repeat: no-repeat;
+        cursor: pointer;
+    }
+    &-indicator {
+        background-image: url(../../../static/images/thumbnail-indicator.png);
+        background-position: center;
+        background-size: contain;
+        background-repeat: no-repeat;
+        cursor: pointer;
+    }
+    &-empty {
+        background-image: url(../../../static/images/thumbnail-default.png);
+        background-position: center;
+        background-size: contain;
+        background-repeat: no-repeat;
+        cursor: pointer;
+        opacity: .3;
+    }
+}

+ 0 - 14
src/themes/default/chart.less

@@ -24,20 +24,6 @@
             }
             &> .ant-card-body {
                 background: @content-background-color;
-                .chart-card {
-                    .ant-card {
-                        .ant-card-head {
-                            border: none;
-                            .ant-card-head-wrapper {
-                                background: #D6EEFE;
-                                .label {
-                                    font-size: 14px;
-                                    color: #2C82BE;
-                                }
-                            }
-                        }
-                    }
-                }
             }
         }
     }