react+ antd+ echarts 表格显示

 

/**
 * @file modules/dashboard/Index
 * @author sun
 */

import _ from 'lodash';
import moment from 'moment';
import echarts from 'echarts';
import 'echarts/lib/component/legendScroll';
import {Row, Col, Card, DatePicker, Table, message, Divider} from 'antd';
import {components, utils} from 'baidu-acu-react-common';

import {OverviewItem} from 'constants/constants';

import './Index.less';

const RangePicker = DatePicker.RangePicker;
const {toDate} = utils.timeUtil;

const legendData = OverviewItem.toArray().map(d => d.text);
const legendUnit = OverviewItem.toArray().map(d => d.unit);
const legend = OverviewItem.toArray().map(d => d.legend);
const legendStr = OverviewItem.toArray().map(d => d.value);
const legendvalue = OverviewItem.toArray().map(d => d.legendvalue);
const initSelected = {'请求量': false, '展现量': false, '点击量': false, '展现率': false,
             '点击率': false, '收入': false, 'CPM': true, 'CPC': true};
/* globals React */
export default class HomePage extends React.Component {

    state = {
        rangePickerValue: [],
        statis: {
            imp: {today: 0, yesterday: 0, lastSevenDays: 0},
            cost: {},
            plan: {},
            app: {},
            slot: {},
            strategy: {},
            cpm: {}
        },
        impData: {
            request: []
        },
        topData: {
            app: [],
            plan: [],
            adx: []
        },
        selected: initSelected,
        legValue: ['CPM', 'CPC'],
        yAxisValue: [{}, {}, {}]

    }
    componentDidMount() {
        // this.loadSystem();
        this.loadStat();
        this.loadYaxis();
        this.selectDate(0, 6);
    }
    loadStat = () => {
        const {actions} = this.props;
        actions.getHomeStat({}).then(res => {
            this.setState({statis: res});
        });
    }
    loadYaxis() {
        const {legValue} = this.state;
        let yAxisValue = [{
            name: legendUnit[legendData.indexOf(legValue[0])],
            position: 'left',
            splitLine: {show: false},
            nameTextStyle: {
                color: ['#118DEE']
            },
            axisLine: {
                lineStyle: {
                    color: '#118DEE'
                }
            },
            type: 'value'
        },
        {name: legendUnit[legendData.indexOf(legValue[1])],
            splitLine: {show: false},
            nameTextStyle: {
                color: ['#5FB333']
            },
            axisLine: {
                lineStyle: {
                    color: '#5FB333'
                }
            },
            position: 'right',
            type: 'value'
        }, {}];
        this.setState({yAxisValue});
    }
    loadchartDaily() {
        const _this = this;
        const actions = this.props.actions;
        const {rangePickerValue} = this.state;

        const topParam = {
            startTime: toDate(rangePickerValue[0]),
            endTime: toDate(rangePickerValue[1])
        };

        actions.getHomeImp(topParam).then(chartDaily => {
            let chartDom = document.getElementById('chart-main');
            let myChart = echarts.init(chartDom);
            let title = '';
            window.onresize = function () {
                myChart.resize();
            };
            myChart.on('legendselectchanged', function (params) {
                title = '';
                let {selected, name} = params;
                // 改变title
                // this.props.chart
                let {legValue} = _this.state;
                if (legValue.indexOf(name) === -1) {
                    legValue.push(name);
                }
                if (legValue.length > 2) {
                    selected[legValue[0]] = false;
                    legValue = [legValue[1], legValue[2]];
                }
                if (legValue.length === 2) {
                    selected[legValue[0]] = true;
                    selected[legValue[1]] = true;
                }
                legValue.map(d => {
                    // 将选中的加入到title中去
                    let i = legendData.indexOf(d);
                    let value = (chartDaily[legendvalue[i]]) || 0;
                    let unit = legendUnit[i];
                    title += legend[i] + ':' + (unit === '元' ? '¥' : '') + (unit === '次' ? value : value.toFixed(2))
                        + unit + ',';
                });
                _this.setState({title, selected, legValue}, () => {
                    _this.loadYaxis();
                });
            });
        });
    }
    loadTop() {
        const actions = this.props.actions;
        const {rangePickerValue} = this.state;

        const topParam = {
            startTime: toDate(rangePickerValue[0]),
            endTime: toDate(rangePickerValue[1])
        };
        actions.getHomeTop(topParam).then(res => {
            res.app = this.addIndex(res.app);
            res.plan = this.addIndex(res.plan);
            res.adx = this.addIndex(res.adx);
            this.setState({topData: res});
        });
    }


    getTimeDistance(bd = 0, ed = 0) {
        const begin = moment().subtract(bd, 'day').toDate();
        const end = moment().subtract(ed, 'day').endOf('day').toDate();
        begin.setHours(0, 0, 0, 0);
        end.setHours(24, 0, 0, 0);
        return [moment(end), moment(begin)];
    }

    selectDate = (bd, ed) => {
        this.setState({
            rangePickerValue: this.getTimeDistance(bd, ed)
        }, () => {
            this.loadchartDaily();
            this.loadTop();
        });
    };

    handleRangePickerChange = rangePickerValue => {
        if (!rangePickerValue[1]) {
            rangePickerValue[1] = rangePickerValue[0];
        }
        this.setState({
            rangePickerValue
        }, () => {
        // 时间变化时,重新加载图表
            this.loadchartDaily();
            this.loadTop();
        });
    }
    formatNumber(param) {
        return parseFloat(param).toFixed(2);
    }
    initChartData(chartDaily) {
        const _this = this;
        if (chartDaily.request) {
            let result = {
                date: chartDaily.request.map(d => d.date)
            };
            _.each(legendStr, function (val) {
                result[val] = [];
                const value = chartDaily[val];
                const len = value.length;
                for (let i = 0; i < len; i++) {
                    result[val][i] = Number(_this.formatNumber(value[i].value));
                }
            });
            return result;
        }
    }
    initTopTable(name) {
        const columns = [
            {
                title: '排名',
                dataIndex: 'index',
                key: 'index',
                render(item) {
                    if (item === 1) {
                        return (<img style={{width: 20, height: 20}} src='/static/img/top1.svg' />);
                    }
                    if (item === 2) {
                        return (<img style={{width: 20, height: 20}} src='/static/img/top2.svg' />);
                    }
                    if (item === 3) {
                        return (<img style={{width: 20, height: 20}} src='/static/img/top3.svg' />);
                    }
                    return 'NO.' + item;
                }
            },
            {
                title: name,
                dataIndex: 'name',
                key: 'name'
            },
            {
                title: '收入',
                dataIndex: 'cost',
                key: 'cost',
                render(item) {
                    return Math.floor(item * 100) / 100;
                }
            },
            {
                title: '占比',
                dataIndex: 'percent',
                key: 'percent',
                render(item) {
                    return item.toFixed(2) + '%';
                }
            }
        ];
        return columns;
    }
    addIndex(data) {
        if (data) {
            data.map(function (item, index) {
                item.index = index + 1;
            });
            return data;
        }
    }
    formatParam(param, init) {
        if (param) {
            return param.toFixed(2);
        }
        return init;
    }
    disabledDate = current => current && current > moment().endOf('day');
    render() {
        const {topData, statis, selected, legValue, yAxisValue} = this.state;
        const chartDaily = this.props.chart || {};
        let {title} = this.state;
        const initDara = this.initChartData(chartDaily);
        const {date} = initDara || {};
        const {app, plan, adx} = topData;
        // const date = request.map(d => d.date);
        let seriesData = [];
        let color = [];
        legendData.map(d => {
            let datas  = initDara ? initDara[legendStr[legendData.indexOf(d)]] : [];
            let index = legValue.indexOf(d);
            seriesData.push({
                name: d,
                type: 'line',
                yAxisIndex: index === -1 ? 2 : index,
                data: legValue.indexOf(d) > -1 ? datas : [],
                lineStyle: {
                    normal: {
                        color: d === legValue[0] ? '#118DEE' : '#5FB333'
                    }
                },
                smooth: true
            });
            color.push(d === legValue[0] ? '#118DEE' : '#5FB333');
        });
        // 基于准备好的dom,初始化ECharts实例
        let chartDom = document.getElementById('chart-main');
        let cpmValue = chartDaily.cpmSum || 0;
        let cpcValue = chartDaily.cpcSum || 0;
        let titleInit = '平均CPM:¥' + cpmValue.toFixed(2) + '元,平均CPC:¥' + cpcValue.toFixed(2) + '元';
        if (title === undefined) {
            title = titleInit;
        }
        let title1 = title.split(',')[0].split(':');
        let title2 = title.split(',')[1].split(':');
        let titleHtml = (<span>
            <span className='chart-legend'>{title1[0]}:</span>
            <span className='chart-legend'style={{marginLeft: '3%', color: '#118DEE'}}>{title1[1]}</span>
            <span className='chart-legend'style={{marginLeft: '5%'}}>{title2[0]}:</span>
            <span className='chart-legend'style={{marginLeft: '3%', color: '#5FB333'}}>{title2[1]}</span>
        </span>);
        // 更换组件为echarts
        // 根据选中选中的图例, 更换Y轴
        if (chartDom) {
            const myChart = echarts.init(chartDom);
            let options = {
                grid: [
                    {
                        left: '10%',
                        right: '8%',
                        bottom: 100
                    }
                ],
                dataZoom: [{
                    type: 'slider',
                    bottom: 40
                }],
                color,
                xAxis: [{
                    // x轴数据
                    data: date,
                    type: 'category',
                    // x轴两边留白策略 默认为true,不留白
                    boundaryGap: false
                }],
                yAxis: yAxisValue,
                tooltip: {
                    trigger: 'axis',
                    axisPointer: {
                        lineStyle: {
                            color: '#108cee'
                        }
                    },
                    position(pt) {
                        return [pt[0], '10%'];
                    },
                    backgroundColor: '#fff',
                    textStyle: {
                        color: '#333'
                    },
                    enterable: false,
                    extraCssText: 'border-radius:0;'
                    + 'padding:0;'
                    + 'background-color:rgba(255,255,255,.95);'
                    + 'box-shadow:3px 3px 9px 3px rgba(16,140,238,.3);',
                    formatter(params, ticket, callback) {
                        let axisLabel = '';
                        const domArray = _.map(params, item => {
                            const {axisValue, data, seriesName, seriesIndex} = item;
                            const value = /\./g.test(data) ? data.toFixed(2) : data;
                            const unit = legendUnit[legendData.indexOf(seriesName)];
                            axisLabel = new Date(axisValue).toLocaleDateString();
                            return `
                                ${seriesName}:
                                <span>${value}${unit}</span>
                            `;
                        });
                        let domdata = '';
                        for (let dom of domArray) {
                            domdata += '<div> <strong>' + dom + '</strong> </div>';
                        }
                        return `
                            <dl>
                                <dt>${axisLabel} 详情</dt>
                                <dd>
                                ${domdata}
                                </dd>
                            </dl>
                        `;
                        /* eslint-enable */
                    }
                },
                legend: {
                    type: 'scroll',
                    bottom: 10,
                    data: legendData,
                    selected: selected
                },
                series: seriesData
            };
            myChart.clear();
            myChart.setOption(options);
        }
        // top数据 SITE,IDEA,PROV
        const appColums = this.initTopTable('站点/APP');
        const planColums = this.initTopTable('广告订单');
        const adxColums = this.initTopTable('广告平台');
        return (
            <Row gutter={16}>
                <Col span={24}>
                    <Card>
                        <div className='statistic-item-none-wrap'>
                            <div className="bill-info">
                                {statis.imp.today || 0}
                            </div>
                            <div className="description">
                                今日展现量
                            </div>
                            <div className="description">
                                昨日: {statis.imp.yesterday || 0}
                            </div>
                            <div className="description">
                                7日平均: {statis.imp.lastSevenDays || 0}
                            </div>
                        </div>
                        <div className='statistic-item'>
                            <div className="bill-info">
                            ¥{this.formatParam(statis.cost.today, '0.00')}
                            </div>
                            <div className="description">
                                今日收入
                            </div>
                            <div className="description">
                                昨日: ¥{this.formatParam(statis.cost.yesterday, '0.00')}
                            </div>
                            <div className="description">
                                7日平均: ¥{this.formatParam(statis.cost.lastSevenDays, '0.00')}
                            </div>
                        </div>
                        <div className='statistic-item'>
                            <div className="bill-info">
                                ¥ {this.formatParam(statis.cpm.today, '0.00')}
                            </div>
                            <div className="description">
                                今日CPM
                            </div>
                            <div className="description">
                                昨日: ¥{this.formatParam(statis.cpm.yesterday, '0.00')}
                            </div>
                            <div className="description">
                                7日平均: ¥{this.formatParam(statis.cpm.lastSevenDays, '0.00')}
                            </div>
                        </div>
                        <div className='statistic-item'>
                            <div className="bill-info">
                                {statis.slot.enabled}/{statis.slot.total}
                            </div>
                            <div className="description">
                                启用的广告位数量/总量
                            </div>
                            <div className="bill-info">
                                {statis.plan.enabled}/{statis.plan.total}
                            </div>
                            <div className="description">
                                进行中的订单数量/总量
                            </div>
                        </div>
                        <div className='statistic-item'>
                            <div className="bill-info">
                                {statis.app.enabled}/{statis.app.total}
                            </div>
                            <div className="description">
                                启用的流量源数量/总量
                            </div>
                            <div className="bill-info">
                                {statis.strategy.enabled}/{statis.strategy.total}
                            </div>
                            <div className="description">
                                进行中的投放数量/总量
                            </div>
                        </div>
                    </Card>
                </Col>
                <Col span={24}>
                    <Row style={{marginTop: 10}}>
                        <div className="x-date-chart-legend">
                            <div className="chart-date">
                                <RangePicker
                                    value={this.state.rangePickerValue}
                                    onChange={this.handleRangePickerChange}
                                    disabledDate={this.disabledDate}
                                />
                            </div>
                            <div className="charts">
                                <div className='chart-legend message-center'>
                                    {titleHtml}
                                </div>
                                <div id='chart-main' style={{width: '100%', height: 300}} ></div>
                            </div>
                        </div>
                    </Row>
                </Col>
                <Col span={8}>
                    <Row style={{marginTop: 10}}>
                        <Card
                            loading={!app}
                        >
                            <span className='top-item-title'>
                                流量源收入排行
                            </span>
                            <Table dataSource={app} columns={appColums} pagination={false} rowKey='id' />;
                        </Card>
                    </Row>
                </Col>
                <Col span={8}>
                    <Row style={{marginTop: 10}}>
                        <Card
                            loading={!plan}
                        >
                            <span className='top-item-title'>
                                广告订单收入排行
                            </span>
                            <Table dataSource={plan} columns={planColums} pagination={false} rowKey='id' />;
                        </Card>
                    </Row>
                </Col>
                <Col span={8}>
                    <Row style={{marginTop: 10}}>
                        <Card
                            loading={!adx}
                        >
                            <span className='top-item-title'>
                                广告平台收入排行
                            </span>
                            <Table dataSource={adx} columns={adxColums} pagination={false} rowKey='id' />
                        </Card>
                    </Row>
                </Col>
            </Row>
        );
    }
}

css

/**
 * @file cluster列表样式配置
 * @author Chen Bo (chenbo09@baidu.com)
 */
 .nomargin {
    margin-left: 0 !important;
    margin-right:0 !important;
}
.message-center {
    text-align: center
}
svg {
    color: #2f9df6;
    fill: currentColor;
}
.orange {
    color: #EA2E2E;
}

.green {
    color: #5EB432;
}

.bill-info {
    cursor:pointer;
}

dt {
    background-color: #1694f3;
    padding: 5px 10px;
    color: #fff;
    font-size: 12px;
    margin-bottom: 0;
  }
dd {
    padding: 5px 10px;
    color: #666;
    max-height: 200px;
    overflow: auto;
    div {
        margin: 0 -10px;
        padding: 0 10px;
        min-width: 100px;
        overflow: hidden;
        font-size: 12px;
    }
    strong {
        color: #108cee;
    }
  }
.sum {
    margin-left: 20%
}

.statistic-item-none-wrap {
    display: inline-block;
    margin: 10px;
    width: 17%;

    font-size: 18px;
    line-height: 18px;
    padding-left: 2%;
    div {
        margin: 10px 0;
    }
    .description {
        font-size: 9px;
    }
}
.statistic-item {
    display: inline-block;
    margin: 10px;
    font-size: 18px;
    width: 17%;

    line-height: 18px;
    border-left: 1px solid #E5E5E5;
    padding-left: 2%;
    div {
        margin: 10px 0;
    }
    .description {
        font-size: 9px;
    }
}
.bill-info {
    cursor:pointer; // 鼠标悬浮时显示为手指
    font-size: 22px;
}
.started-plan, .all-plan, .started-unit, .all-unit, .started-idea, .all-idea, .passed-audit, .all-audit:hover {
    cursor:pointer;
}
.rank-first {
    background: url('/static/img/top1.svg');

}
.rank-second {
    background-image: url('/static/img/top2.svg');
    width: 10px;
    height: 10px;
}
.rank-third {
    background: url('/static/img/top3.svg');
}
.chart-date {
    font-size: 12px;
    color: #108CEE;
    line-height: 20px;
    padding: 20px 30px;
}
#chart-main {
    text-align: center
}
.x-date-chart-legend {
    background: #FFFFFF;
    border: 1px solid #E5E5E5;
    .chart-date {
        font-size: 12px;
        color: #108CEE;
        line-height: 20px;
        padding: 20px 30px;
        border-bottom: 1px solid #E5E5E5;
    }
    .chart-legend {
        padding: 20px 30px;
        font-size: 18px;

    }
    .charts {
        padding: 0 30px 20px 30px;
        border-bottom: 1px solid #E5E5E5;
        .chart-content {
            position: relative;
            .chart-no-date {
                font-size: 18px;
                position: absolute;
                top: 30%;
                left: 45%
            }
        }
    }
}
.top-item-title {
    border-left: 4px solid #108CEE;
    padding-left: 14px;
    margin: 0 0 20px 0;
    font-size: 16px;
    color: #333333;
    line-height: 16px;
}

页面效果

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hero_孙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值