
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
-->

<html>
    <head>
        <meta charset="utf-8">
        <script src="lib/esl.js"></script>
        <script src="lib/config.js"></script>
    </head>
    <body>
        <style>
            html, body, #main {
                width: 100%;
                height: 100%;
            }
        </style>
        <div id="main"></div>
        <script>

            require([
                'echarts'
                // 'echarts/chart/line',
                // 'echarts/component/legend',
                // 'echarts/component/grid',
                // 'echarts/component/tooltip',
                // 'echarts/component/markLine'
            ], function (echarts) {

                var chart = echarts.init(document.getElementById('main'));

                var xAxisData = [];
                var data1 = [];
                var data2 = [];

                for (var i = 0; i < 10; i++) {
                    xAxisData.push('类目' + i);
                    data1.push(+Math.random().toFixed(2));
                    data2.push(+Math.random().toFixed(2));
                }

                var markLine1 = [];
                var markLine2 = [];
                var positions = [
                    'start', 'middle', 'end',
                    'insideStart', 'insideStartTop', 'insideStartBottom',
                    'insideMiddle', 'insideMiddleTop', 'insideMiddleBottom',
                    'insideEnd', 'insideEndTop', 'insideEndBottom'
                ];
                for (var i = 0; i < positions.length; ++i) {
                    markLine1.push({
                        name: positions[i],
                        yAxis: 1.8 - 0.2 * Math.floor(i / 3),
                        label: {
                            formatter: '{b}',
                            position: positions[i]
                        }
                    });
                    markLine1.push([{
                        name: 'start: ' + positions[i],
                        type: 'min',
                        label: {
                            formatter: positions[i],
                            position: positions[i]
                        }
                    }, {
                        name: 'end: ' + positions[i],
                        type: 'max'
                    }]);

                    markLine2.push({
                        name: positions[i],
                        xAxis: Math.floor(i / 3),
                        label: {
                            formatter: '{b}',
                            position: positions[i]
                        }
                    });
                    markLine2.push([{
                        name: 'start: ' + positions[i],
                        type: 'min',
                        valueIndex: 0,
                        label: {
                            formatter: positions[i],
                            position: positions[i]
                        }
                    }, {
                        name: 'end: ' + positions[i],
                        valueIndex: 0,
                        type: 'max'
                    }]);
                }

                chart.setOption({
                    animation: false,
                    color: ['#f60', '#0c6'],
                    legend: {
                        data: ['line', 'line2']
                    },
                    tooltip: {
                        trigger: 'axis',
                        axisPointer: {
                            type: 'line'
                        }
                    },
                    xAxis: {
                        // data: ['类目1', '类目2', '类目3', '类目4', '类目5',]
                        data: xAxisData,
                        boundaryGap: true,
                        // inverse: true,
                        splitArea: {
                            show: true
                        }
                    },
                    yAxis: {
                        splitLine: {
                            // show: false
                        },
                        max: 2
                    },
                    series: [{
                        name: 'line',
                        type: 'line',
                        stack: 'all',
                        symbolSize: 6,
                        data: data1,

                        markLine: {
                            data: markLine1
                        }
                    }, {
                        name: 'line2',
                        type: 'line',
                        stack: 'all',
                        symbolSize: 6,
                        data: data2,

                        markLine: {
                            data: markLine2,
                            label: {
                                distance: [20, 5]
                            }
                        }
                    }]
                });

                chart.on('click', function (params) {
                    console.log(params, params.data);
                });

            });

        </script>
    </body>
</html>