股票K线图,折线图总结(echarts)

此处利用bootstrap+echarts画布配置参数实现响应式,并且利用socket实时通信实现数据的实时更新

(一)介绍

  1. ECharts (Enterprise Charts 商业产品图表库)
  2. ECharts开源来自百度商业前端数据可视化团队,基于html5 Canvas,是一个纯Javascript
    图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表。创新的拖拽重计算、数据视图、值域漫游等特性大大增强了用户体验,赋予了用户对数据进行挖掘、整合的能力。 提供商业产品常用图表,底层基于ZRender
  3. (一个全新的轻量级canvas类库),创建了坐标系,图例,提示,工具箱等基础组件,并在此上构建出折线图(区域图)、柱状图(条状图)、散点图(气泡图)、饼图(环形图)、K
    线图、地图、力导向布局图以及和弦图,
  4. 同时支持任意维度的堆积和多图表混合展现。 优势:拖拽重计算,大规模数据模式直角系图表(折、柱、散点、K线)
  5. 20万数据秒级出图,拥有值域漫游的功能,让你可以轻松进行数值筛选。

(二)使用

一、插件的下载(echarts+bootstrap)

  1. echarts

    地址:http://echarts.baidu.com/download.html

    或者使用npm拉取:npm install echarts --save

    详情查看官网手册:http://echarts.baidu.com/tutorial.html#%E5%9C%A8%20webpack%20%E4%B8%AD%E4%BD%BF%E7%94%A8%20ECharts

  2. bootstrap
    地址:http://v3.bootcss.com/getting-started/#download

二、引入echarts+bootstrap+socket.io

  1. echarts

    只需要像普通的 JavaScript 库一样用 script 标签引入。

    代码如下:

     <!DOCTYPE html>
     <html>
     <header>
         <meta charset="utf-8">
         <!-- 引入 ECharts 文件 -->
         <script src="echarts.min.js"></script>
         <script type="text/javascript" src="/statics/js/echarts/echarts-all-3.js"></script>
         <script type="text/javascript" src="/statics/js/echarts/extension/dataTool.min.js"></script>
         <script type="text/javascript" src="/statics/js/echarts/map/china.js"></script>
         <script type="text/javascript" src="/statics/js/echarts/map/world.js"></script>
         <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=ZUONbpqGBsYGXNIYHicvbAbM"></script>
         <script type="text/javascript" src="/statics/js/echarts/extension/bmap.min.js"></script>
         <script src="/statics/js/socket.io.js"></script>
         <script src="/statics/js/echarts/echarts.js"></script>
     </header>
     </html>
    
  2. bootstrap

    我这里设置的啦ravel路径,根据自己情况,自行设置
    <link rel="stylesheet" href="/statics/css/bootstrap/bootstrap.min.css">
    <link rel="stylesheet" href="/statics/css/bootstrap/bootstrap-theme.min.css">
    <script src="/statics/js/bootstrap/bootstrap.min.js"></script>

  3. socket.io
    <script src="/statics/js/socket.io.js"></script>

三、绘制一个简单的图表

  1. 在绘图前我们需要为 ECharts 准备一个具备高宽的 DOM 容器。

    body里设置一个div放置画布使用

    代码如下:

     <body style="height:100%">
     <nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
         <div class="container" style="height: 601px;width: 100%" id="container">
             <form method="post">{{csrf_field()}}</form>//此处为csrftoken认证,防止跨域攻击
         </div>
         @yield('content')//这里利用了laravel的模板继承
     </nav>
     </body>
    
  2. 通过 echarts.init 方法初始化一个 echarts 实例并通过 setOption 方法生成一个简单的图

    官网完整简单实例代码。
     <!DOCTYPE html>
     <html>
     <head>
         <meta charset="utf-8">
         <title>ECharts</title>
         <!-- 引入 echarts.js -->
         <script src="echarts.min.js"></script>
     </head>
     <body>
         <!-- 为ECharts准备一个具备大小(宽高)的Dom -->
         <div id="main" style="width: 600px;height:400px;"></div>
         <script type="text/javascript">
             // 基于准备好的dom,初始化echarts实例
             var myChart = echarts.init(document.getElementById('main'));
     
             // 指定图表的配置项和数据
             var option = {
                 title: {
                     text: 'ECharts 入门示例'
                 },
                 tooltip: {},
                 legend: {
                     data:['销量']
                 },
                 xAxis: {
                     data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"]
                 },
                 yAxis: {},
                 series: [{
                     name: '销量',
                     type: 'bar',
                     data: [5, 20, 36, 10, 10, 20]
                 }]
             };
     
             // 使用刚指定的配置项和数据显示图表。
             myChart.setOption(option);
         </script>
     </body>
     </html>
    
    我的初始化
> 因为使用了模板继承,将html头部和画布的div初始化到了一个模板中,代码如下
    
文件名:'zoushi.blade.com'
        
        <!DOCTYPE html>
        <html style="height: 100%" lang="en">
        <head>
            <style>
                @media (min-width: 1200px) {
                    .col--2-5 {
                        float: left;
                        width: 8%;
                        margin-right: 1.4%;
                    }
                }
            </style>
            <meta charset="utf-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <meta name="description" content="">
            <meta name="author" content="">
            <title>Starter Template for Bootstrap</title>
            <link rel="stylesheet" href="/statics/css/bootstrap/bootstrap.min.css">
            <link rel="stylesheet" href="/statics/css/bootstrap/bootstrap-theme.min.css">
            <script src="/statics/js/jquery.min.js"></script>
            <script src="/statics/js/bootstrap/bootstrap.min.js"></script>
            <script type="text/javascript" src="/statics/js/echarts/echarts-all-3.js"></script>
            <script type="text/javascript" src="/statics/js/echarts/extension/dataTool.min.js"></script>
            <script type="text/javascript" src="/statics/js/echarts/map/china.js"></script>
            <script type="text/javascript" src="/statics/js/echarts/map/world.js"></script>
            <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=ZUONbpqGBsYGXNIYHicvbAbM"></script>
            <script type="text/javascript" src="/statics/js/echarts/extension/bmap.min.js"></script>
            <script src="/statics/js/socket.io.js"></script>
            <script src="/statics/js/echarts/echarts.js"></script>
        </head>
        <body style="height:100%">
        <nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
            <div class="container" style="height: 601px;width: 100%" id="container">
                <form method="post">{{csrf_field()}}</form>
            </div>
            @yield('content')
        </nav>
        </body>
        </html>
< 一下代码均在js中实现
1. K线图(需要的数据有:开盘价,闭盘价,最高价,最低价,时间)
    1. 获取dom节点初始化
        
            var dom = document.getElementById("container");
            var myChart = echarts.init(dom);
            var app = {};
            option = null;
            app.title = '2015 年上证指数';
            var limit=50;
        
            function calculateMA(dayCount, data) {
                var result = [];
                for (var i = 0, len = data.length; i < len; i++) {
                    if (i < dayCount) {
                        result.push('-');
                        continue;
                    }
                    var sum = 0;
                    for (var j = 0; j < dayCount; j++) {
                        sum += data[i - j][1];
                    }
                    result.push(sum / dayCount);
                }
                return result;
            }
            var data=[['4654','6485','5456','6684']];
            var dates=['122/12/4'];
            require.config({
                paths: {
                    echarts: 'http://echarts.baidu.com/build/dist'
                }
            });
    2. 设置K线图的画布配置参数//详情见代码注释
        
            require(
                    [
                        'echarts',
                        'echarts/chart/bar',// 使用柱状图就加载bar模块,按需加载
                        'echarts/chart/line',
                        'echarts/chart/k',
                    ],
                    function (ec) {
                        // 基于准备好的dom,初始化echarts图表
                        var option = {
                            backgroundColor: '#21202D',
                            legend: {
                                data: ['日K', 'MA5', 'MA10', 'MA20', 'MA30'],
                                inactiveColor: '#777',
                                textStyle: {
                                    color: '#fff'
                                }
                            },
                            tooltip: {
                                trigger: 'axis',
                                axisPointer: {
                                    animation: false,
                                    lineStyle: {
                                        color: '#376df4',
                                        width: 2,
                                        opacity: 1
                                    }
                                }
                            },
                            toolbox: {
                                show: true,
                                feature: {
                                    dataZoom: {
                                        yAxisIndex: 'none'
                                    },
                                    dataView: {readOnly: false},
                                    magicType: {type: ['line', 'bar']},
                                    restore: {},
                                    saveAsImage: {}
                                }
                            },
                            xAxis: {
                                type: 'category',
                                data: dates,
                                axisLine: { lineStyle: { color: '#8392A5' } }
                            },
                            yAxis: {
                                min:'100%',
                                scale: true,
                                axisLine: { lineStyle: { color: '#8392A5' } },
                                splitLine: { show: false }
                            },
                            dataZoom: [{
                                textStyle: {
                                    color: '#8392A5'
                                },
                                handleIcon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
                                handleSize: '80%',
                                dataBackground: {
                                    areaStyle: {
                                        color: '#8392A5'
                                    },
                                    lineStyle: {
                                        opacity: 0.8,
                                        color: '#8392A5'
                                    }
                                },
                                handleStyle: {
                                    color: '#fff',
                                    shadowBlur: 3,
                                    shadowColor: 'rgba(0, 0, 0, 0.6)',
                                    shadowOffsetX: 2,
                                    shadowOffsetY: 2
                                }
                            }, {
                                type: 'inside'
                            }],
                            animation: false,
                            series: [
        
                                {
                                    type: 'candlestick',
                                    name: '日K',
                                    data: data,
                                    markLine: {
                                        symbol: ['none', 'none'],
                                        symbolOffset:[0, '50%'],
                                        data : [
                                            [
                                                {name: '标线2起点', value: data[data.length-1][1], x: '100%', yAxis: data[data.length-1][1]},
                                                {name: '标线2终点', x: '10%', yAxis: data[data.length-1][1]}
                                            ]
                                        ]
        
        
                                    },
        
                                    itemStyle: {
                                        normal: {
                                            color: '#FD1050',
                                            color0: '#0CF49B',
                                            borderColor: '#FD1050',
                                            borderColor0: '#0CF49B'
                                        }
                                    }
                                },
                                {
                                    name: 'MA5',
                                    type: 'line',
                                    data: calculateMA(5, data),
                                    smooth: true,
                                    showSymbol: false,
                                    lineStyle: {
                                        normal: {
                                            width: 1
                                        }
                                    }
                                },
                                {
                                    name: 'MA10',
                                    type: 'line',
                                    data: calculateMA(10, data),
                                    smooth: true,
                                    showSymbol: false,
                                    lineStyle: {
                                        normal: {
                                            width: 1
                                        }
                                    }
                                },
                                {
                                    name: 'MA20',
                                    type: 'line',
                                    data: calculateMA(20, data),
                                    smooth: true,
                                    showSymbol: false,
                                    lineStyle: {
                                        normal: {
                                            width: 1
                                        }
                                    }
                                },
                                {
                                    name: 'MA30',
                                    type: 'line',
                                    data: calculateMA(30, data),
                                    smooth: true,
                                    showSymbol: false,
                                    lineStyle: {
                                        normal: {
                                            width: 1
                                        }
                                    }
                                }
                            ]
                        };
                        // 为echarts对象加载数据
                        myChart.setOption(option);
                    }
            );
    3. 写实时刷新需要改变的参数,封装为刷新函数//详情见代码注释
        
            function refreshData(){
                if(!myChart){
                    return;
                }
                //更新数据
                var option = myChart.getOption();
                option.series[0].data = data;
                option.xAxis[0].dates = dates;
                option.series[0].markLine.data[0][0].value=data[data.length-1][1];
                option.series[0].markLine.data[0][0].yAxis=data[data.length-1][1];
                option.series[0].markLine.data[0][1].value=data[data.length-1][1];
                option.series[0].markLine.data[0][1].yAxis=data[data.length-1][1];
                option.series[1].data=calculateMA(5, data);
                option.series[2].data=calculateMA(10, data);
                option.series[3].data=calculateMA(20, data);
                option.series[4].data=calculateMA(30, data);
                myChart.setOption(option);
                console.log(data[data.length-1])
              }

    4. 利用socket通信,实时监听数据的到来
        
            var socket = io('http://192.168.100.121:6002');
            socket.on('connection', function (data) {
                console.log(data);
            });
            socket.on('zxz:App\\Events\\Push', function(message){
                window.onresize = myChart.resize;
                if(message.open==data[data.length-1][0])
                {
                    data[data.length-1][1]=message.close;
                    data[data.length-1][2]=message.max;
                    data[data.length-1][3]=message.min;
                    refreshData();
                }else{
                    data.push([message.open,message.close,message.max,message.min]);
                    dates.push(message.time);
                    console.log(data.length+"----"+dates.length);
                    if(data.length==limit)
                    {
                        data.shift();
                        dates.shift();
                        refreshData();
                    }else{
                        refreshData();
                    }
                }
            });
2. 折线图(需要的数据有:闭盘价,时间)
    1. 获取dom节点初始化
        
            var dom = document.getElementById("container");
                var myChart = echarts.init(dom);
                var app = {};
                option = null;
                app.title = '2015 年上证指数';
                var limit = 50;
                function calculateMA(dayCount, data) {
                    var result = [];
                    for (var i = 0, len = data.length; i < len; i++) {
                        if (i < dayCount) {
                            result.push('-');
                            continue;
                        }
                        var sum = 0;
                        for (var j = 0; j < dayCount; j++) {
                            sum += data[i - j];
                        }
                        result.push(sum / dayCount);
                    }
                    return result;
                }
                var data = ['4654'];
                var dates = ['122/12/4'];
                require.config({
                    paths: {
                        echarts: 'http://echarts.baidu.com/build/dist'
                    }
                });
    2. 设置折线图的画布配置参数+画布响应式//详情见代码注释
            
            require(
                            [
                                'echarts',
                                'echarts/chart/line'
                            ],
                            function (ec) {
                                // 基于准备好的dom,初始化echarts图表
                                var option = {
                                    baseOption:{
                                        backgroundColor: '#21202D',
                                        legend: {
                                            data: ['折线', 'MA5', 'MA10', 'MA20', 'MA30'],
                                            inactiveColor: '#777',
                                            textStyle: {
                                                color: '#fff'
                                            }
                                        },
                                        tooltip: {
                                            trigger: 'axis',
                                            axisPointer: {
                                                animation: false,
                                                lineStyle: {
                                                    color: '#376df4',
                                                    width: 2,
                                                    opacity: 1
                                                }
                                            }
                                        },
                                        toolbox: {
                                            show: true,
                                            feature: {
                                                dataZoom: {
                                                    yAxisIndex: 'none'
                                                },
                                                dataView: {readOnly: false},
                                                magicType: {type: ['line', 'bar']},
                                                restore: {},
                                                saveAsImage: {}
                                            }
                                        },
                                        xAxis: {
                                            type: 'category',
                                            data: dates,
                                            axisLine: {lineStyle: {color: '#8392A5'}}
                                        },
                                        yAxis: {
                                            position:'right',
                                            scale: true,
                                            axisLine: {lineStyle: {color: '#8392A5'}},
                                            splitLine: {show: false}
                                        },
                                        dataZoom: [{
                                            textStyle: {
                                                color: '#8392A5'
                                            },
                                            handleIcon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
                                            handleSize: '80%',
                                            dataBackground: {
                                                areaStyle: {
                                                    color: '#8392A5'
                                                },
                                                lineStyle: {
                                                    opacity: 0.8,
                                                    color: '#8392A5'
                                                }
                                            },
                                            handleStyle: {
                                                color: '#fff',
                                                shadowBlur: 3,
                                                shadowColor: 'rgba(0, 0, 0, 0.6)',
                                                shadowOffsetX: 2,
                                                shadowOffsetY: 2
                                            }
                                        }, {
                                            type: 'inside',
                                            show:  false
                                        }],
                                        animation: false,
                                        series: [
                                            {
                                                type: 'line',
                                                name: '日K',
                                                data: data,
                                                showSymbol: false,
                                                hoverAnimation: false,
                                                data: data,
                                                markLine: {
                                                    symbol: ['none', 'none'],
                                                    symbolOffset:[0, '50%'],
                                                    data : [
                                                        [
                                                            {name: '标线2起点', value: data[data.length-1], x: 100, yAxis: data[data.length-1]},
                                                            {name: '标线2终点', x: '90%', yAxis: data[data.length-1]}
                                                        ]
                                                    ]
                                                }
                                            },
                                            {
                                                name: 'MA5',
                                                type: 'line',
                                                data: calculateMA(5, data),
                                                smooth: true,
                                                showSymbol: false,
                                                lineStyle: {
                                                    normal: {
                                                        width: 1
                                                    }
                                                }
                                            },
                                            {
                                                name: 'MA10',
                                                type: 'line',
                                                data: calculateMA(10, data),
                                                smooth: true,
                                                showSymbol: false,
                                                lineStyle: {
                                                    normal: {
                                                        width: 1
                                                    }
                                                }
                                            },
                                            {
                                                name: 'MA20',
                                                type: 'line',
                                                data: calculateMA(20, data),
                                                smooth: true,
                                                showSymbol: false,
                                                lineStyle: {
                                                    normal: {
                                                        width: 1
                                                    }
                                                }
                                            },
                                            {
                                                name: 'MA30',
                                                type: 'line',
                                                data: calculateMA(30, data),
                                                smooth: true,
                                                showSymbol: false,
                                                lineStyle: {
                                                    normal: {
                                                        width: 1
                                                    }
                                                }
                                            }
                                        ]
                                    },
                                    media:[{
                                        query:{
                                            maxWidth:500
                                        },
                                        option:{
                                            legend: {
                                                data: ['日K'],
                                                inactiveColor: '#777',
                                                textStyle: {
                                                    color: '#fff'
                                                }
                                            },
                                            toolbox: {
                                                show: false
                                            },
                                            series: [
                                                {
                                                    name: 'MA5',
                                                    showSymbol: false,
                                                    hoverAnimation: false,
                                                    data: data
                                                },
                                                {
                                                    name: 'MA10',
                                                    showSymbol: false,
                                                    hoverAnimation: false,
                                                    data: data
                                                },
                                                {
                                                    name: 'MA20',
                                                    showSymbol: false,
                                                    hoverAnimation: false,
                                                    data: data
                                                },
                                                {
                                                    name: 'MA30',
                                                    showSymbol: false,
                                                    hoverAnimation: false,
                                                    data: data
                                                }
                                            ],
                                            dataZoom: [{show:false}]
                                        }
                                    }
            
                                    ]
            
                                };
                                // 为echarts对象加载数据
                                window.onresize = myChart.resize;
                                myChart.setOption(option);
                            }
                    );        
    3. 写实时刷新需要改变的参数,封装为刷新函数//详情见代码注释
            
            function refreshData() {
                        if (!myChart) {
                            return;
                        }
                        //更新数据
                        var option = myChart.getOption();
                        option.series[0].data = data;
                        option.xAxis[0].dates = dates;
                        option.series[1].data = calculateMA(5, data);
                        option.series[2].data = calculateMA(10, data);
                        option.series[3].data = calculateMA(20, data);
                        option.series[4].data = calculateMA(30, data);
                        option.series[0].markLine.data[0][0].value=data[data.length-1];
                        option.series[0].markLine.data[0][0].yAxis=data[data.length-1];
                        option.series[0].markLine.data[0][1].value=data[data.length-1];
                        option.series[0].markLine.data[0][1].yAxis=data[data.length-1];
                        myChart.setOption(option);
                    }
    4. 利用socket通信,实时监听数据的到来

            var socket = io('http://192.168.100.121:6002');
            socket.on('connection', function (data) {
                 console.log(data);
            });
                    socket.on('zxz:App\\Events\\Push', function (message) {
                        window.onresize = myChart.resize;
                        if (message.open == open) {
                        } else {
                            data.push(message.open);
                            dates.push(message.time);
                            open = message.open;
                            console.log(data.length);
                            if (data.length == limit) {
                                data.shift();
                                dates.shift();
                                refreshData();
                            } else {
                                refreshData();
                            }
                        }
                    });
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335

推荐阅读更多精彩内容