
<!--
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="./node_modules/echarts/dist/echarts.min.js"></script>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
    </head>
    <body>
        <style>
            h1 {
                line-height: 60px;
                height: 60px;
                background: #146402;
                text-align: center;
                font-weight: bold;
                color: #eee;
                font-size: 14px;
            }
            .chart {
                height: 600px;
            }
        </style>

        <div id="main" class="chart"></div>
        <script>

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

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

            for (var i = 0; i < 10; i++) {
                xAxisData.push('类目' + i);
                data1.push(i === 0 ? '-' : (Math.random() * 5).toFixed(2));
                data2.push(-Math.random().toFixed(2));
                data3.push((Math.random() + 0.5).toFixed(2));
                data4.push((Math.random() + 0.3).toFixed(2));
            }

            var itemStyle = {
                normal: {
                    barBorderRadius: 5,
                    label: {
                        show: true,
                        position: 'outside'
                    }
                },
                emphasis: {
                    label: {
                        position: 'outside'
                    },
                    barBorderColor: '#fff',
                    barBorderWidth: 1,
                    shadowBlur: 10,
                    shadowOffsetX: 0,
                    shadowOffsetY: 0,
                    shadowColor: 'rgba(0,0,0,0.5)'
                }
            };

            chart.setOption({
                backgroundColor: '#eee',
                title: {
                    text: '我是柱状图',
                    padding: 20
                },
                legend: {
                    left: 150,
                    inactiveColor: '#abc',
                    borderWidth: 1,
                    data: [{
                        name: 'bar'
                    }, 'bar2', '\n', 'bar3', 'bar4'],
                    selected: {
                        // 'bar': false
                    },
                    // orient: 'vertical',
                    // x: 'right',
                    // y: 'bottom',
                    align: 'left',

                    tooltip: {
                        show: true
                    }
                },
                brush: {
                    xAxisIndex: 0
                },
                toolbox: {
                    top: 50,
                    // right: 20,
                    feature: {
                        magicType: {
                            type: ['line', 'bar', 'stack', 'tiled']
                        },
                        dataView: {},
                        saveAsImage: {
                            pixelRatio: 2
                        },
                        brush: {
                            type: ['rect', 'polygon', 'lineX', 'lineY', 'keep', 'clear']
                        },
                        restore: {},
                        dataZoom: {
                            yAxisIndex: false
                        },
                        myTool1: {
                            show: true,
                            title: '自定义扩展方法1',
                            icon: 'path://M432.45,595.444c0,2.177-4.661,6.82-11.305,6.82c-6.475,0-11.306-4.567-11.306-6.82s4.852-6.812,11.306-6.812C427.841,588.632,432.452,593.191,432.45,595.444L432.45,595.444z M421.155,589.876c-3.009,0-5.448,2.495-5.448,5.572s2.439,5.572,5.448,5.572c3.01,0,5.449-2.495,5.449-5.572C426.604,592.371,424.165,589.876,421.155,589.876L421.155,589.876z M421.146,591.891c-1.916,0-3.47,1.589-3.47,3.549c0,1.959,1.554,3.548,3.47,3.548s3.469-1.589,3.469-3.548C424.614,593.479,423.062,591.891,421.146,591.891L421.146,591.891zM421.146,591.891',
                            onclick: function (){
                                alert('myToolHandler1')
                            }
                        },
                        myTool2: {
                            show: true,
                            title: '自定义扩展方法2',
                            icon: 'image://http://echarts.baidu.com/images/favicon.png',
                            onclick: function (){
                                alert('myToolHandler2')
                            }
                        }
                    },

                    iconStyle: {
                        emphasis: {
                            textPosition: 'top'
                            // textAlign: 'right'
                        }
                    }
                },
                tooltip: {},
                grid: {
                    top: 100
                },
                xAxis: {
                    data: xAxisData,
                    name: '横轴',
                    silent: false,
                    axisTick: {
                        alignWithLabel: true
                    },
                    // axisLabel: {
                    //     show: false
                    // },
                    // axisTick: {
                    //     show: false
                    // },
                    axisLine: {
                        onZero: true
                        // lineStyle: {
                        //     width: 5
                        // }
                    },
                    splitLine: {
                        show: true
                    },
                    splitArea: {
                        show: true
                    }
                },
                yAxis: {
                    inverse: true,
                    // axisLabel: {
                    //     show: false
                    // },
                    // axisLine: {
                    //     lineStyle: {
                    //         width: 5
                    //     }
                    // },
                    axisTick: {
                        show: false
                    },
                    // splitLine: {
                    //     show: false
                    // },
                    splitArea: {
                        show: false
                    }
                },
                series: [{
                    name: 'bar',
                    type: 'bar',
                    stack: 'one',
                    itemStyle: itemStyle,
                    cursor: 'move',
                    data: data1
                }, {
                    name: 'bar2',
                    type: 'bar',
                    stack: 'one',
                    itemStyle: itemStyle,
                    cursor: 'default',
                    data: data2
                }, {
                    name: 'bar3',
                    type: 'bar',
                    stack: 'two',
                    itemStyle: itemStyle,
                    data: data3
                }, {
                    name: 'bar4',
                    type: 'bar',
                    stack: 'two',
                    itemStyle: itemStyle,
                    data: data4
                }]
            });

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

            chart.on('legendselectchanged', function (params) {
                chart.setOption({
                    // title: {
                    // },
                    graphic: [{
                        type: 'circle',
                        shape: {
                            cx: 100,
                            cy: 100,
                            r: 20,
                        }
                    }]
                });
            });

            window.onresize = chart.resize;

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