
<!--
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/simpleRequire.js"></script>
        <script src="lib/config.js"></script>
        <script src="lib/dat.gui.min.js"></script>
    </head>
    <body>
        <style>
            html, body, #main {
                width: 100%;
                height: 100%;
                margin: 0;
            }
        </style>
        <div id="main"></div>
        <script>

            require([
                'echarts'
            ], function (echarts) {

                var chart = echarts.init(document.getElementById('main'), null, {

                });

                var itemStyle = {
                    normal: {
                        borderWidth: 0
                    },
                    emphasis: {
                        shadowBlur: 40,
                        shadowOffsetX: 0,
                        shadowOffsetY: 0,
                        shadowColor: 'rgba(0, 0, 0, 0.4)',
                        borderWidth: 2
                    }
                };

                chart.setOption({
                    aria: {
                        show: true
                    },
                    title : {
                        text: '漏斗图',
                        subtext: '纯属虚构'
                    },
                    tooltip : {
                        trigger: 'item',
                        formatter: '{a} <br/>{b} : {c}%'
                    },
                    legend: {
                        data : ['展现','点击','访问','咨询','订单']
                    },
                    series: [
                        {
                            name:'漏斗图',
                            type:'funnel',
                            gap: 3,
                            itemStyle: itemStyle,
                            left: 300,
                            right: 300,
                            sort: 'ascending',
                            orient: 'horizontal',
                            label: {
                                normal: {
                                    position: 'leftTop'
                                }
                            },
                            data:[
                                {value:60, name:'访问'},
                                {value:40, name:'咨询'},
                                {value:20, name:'订单'},
                                {
                                    value:80,
                                    name:'点击',
                                    itemStyle: {
                                        height: '10%'
                                    },
                                    label: {
                                        position: 'insideLeft'
                                    }
                                },
                                {
                                    value:100,
                                    name:'展现',
                                    itemStyle: {
                                        height: '30%'
                                    },
                                    label: {
                                        position: 'insideRight'
                                    }
                                }
                            ]
                        }
                    ]
                });

                var config = {
                    sort: 'ascending',
                    orient: 'vertical',
                    labelPosition: 'inside',
                    labelLineLen: 20
                };

                function update() {
                    chart.setOption({
                        series: [{
                            name: '漏斗图',
                            sort: config.sort,
                            orient: config.orient,
                            label: {
                                normal: {
                                    position: config.labelPosition
                                }
                            },
                            labelLine: {
                                normal: {
                                    length: config.labelLineLen
                                }
                            }
                        }]
                    });
                }

                var gui = new dat.GUI();
                gui.add(config, 'sort', ['descending', 'ascending', 'none'])
                    .onChange(update);
                gui.add(config, 'orient', ['vertical', 'horizontal'])
                    .onChange(update);
                gui.add(config, 'labelPosition', ['inside', 'center', 'insideLeft', 'insideRight', 'left', 'right', 'top', 'bottom', 'leftTop', 'leftBottom', 'rightTop', 'rightBottom'])
                    .onChange(update);
                gui.add(config, 'labelLineLen', 0, 100)
                    .onChange(update);
            });

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