<!DOCTYPE html>
<!--
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">
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <script src="lib/simpleRequire.js"></script>
    <script src="lib/config.js"></script>
    <script src="lib/jquery.min.js"></script>
    <script src="lib/facePrint.js"></script>
    <script src="lib/testHelper.js"></script>
    <!-- <script src="ut/lib/canteen.js"></script> -->
    <link rel="stylesheet" href="lib/reset.css" />
</head>

<body>
    <style>
    </style>



    <div id="main0"></div>

    <div id="main1"></div>

    <div id="main2"></div>

    <div id="main3"></div>









    <script>
        require(['echarts'], function (echarts) {
            var option = {
                tooltip: {
                    formatter: "{a} <br/>{b} : {c}%"
                },
                series: [
                    {
                        name: 'Pressure',
                        type: 'gauge',
                        detail: {formatter: '{value}%', valueAnimation: true},
                        data: [{value: 50, name: 'score'}]
                    }
                ]
            };

            var chart = testHelper.create(echarts, 'main0', {
                title: [
                    'Simple gauge',
                    'Value should be 88 after clicking button'
                ],
                option: option,
                buttons: [{
                    text: 'Change data', onclick: function () {
                        option.series[0].data[0].value = 88;
                        chart.setOption(option, true);
                    }
                }]
            });
        });
    </script>






    <script>
        require(['echarts'], function (echarts) {
            var option = {
                tooltip: {
                    formatter: "{a} <br/>{b} : {c}%"
                },
                dataset: {
                    source: [[10], [30]]
                },
                series: [
                    {
                        name: 'Pressure',
                        type: 'gauge',
                        detail: {formatter: '{value}%'}
                    }
                ]
            };

            var chart = testHelper.create(echarts, 'main1', {
                title: [
                    'Gauge with dataset',
                    'Value should be 44 and 88 after clicking button'
                ],
                option: option,
                buttons: [{
                    text: 'Change data', onclick: function () {
                        chart.setOption({
                            dataset: {
                                source: [[44], [88]]
                            }
                        });
                    }
                }]
            });
        });
    </script>




    <script>
        require(['echarts'], function (echarts) {
            var option = {
                tooltip: {
                    formatter: "{a} <br/>{b} : {c}%"
                },
                series: [
                    {
                        name: 'Pressure',
                        type: 'gauge',
                        data: [{}]
                    }
                ]
            };

            var chart = testHelper.create(echarts, 'main2', {
                title: [
                    'Gauge with no data, should display NaN'
                ],
                option: option
            });
        });
    </script>

    <script>
        require(['echarts'], function (echarts) {
            var option = {
                tooltip: {
                    formatter: '{a} <br/>{b} : {c}%'
                },
                toolbox: {
                    feature: {
                        restore: {},
                        saveAsImage: {}
                    }
                },
                series: [{
                    name: '学生成绩',
                    type: 'gauge',
                    startAngle: 180,
                    endAngle: 0,
                    min: 0,
                    max: 1,
                    splitNumber: 8,
                    axisLine: {
                        lineStyle: {
                            width: 5,
                            color: [
                                [0.25, '#FF6E76'],
                                [0.5, '#FDDD60'],
                                [0.75, '#58D9F9'],
                                [1, '#7CFFB2'],
                            ]
                        }
                    },
                    pointer: {
                        length: '80%',
                        itemStyle: {
                            color: 'auto'
                        }
                    },
                    axisTick: {
                        length: 15,
                        lineStyle: {
                            color: 'auto'
                        }
                    },
                    splitLine: {
                        length: 20,
                        lineStyle: {
                            color: 'auto',
                            width: 5
                        }
                    },
                    axisLabel: {
                        color: '#464646',
                        fontSize: 20,
                        distance: -60,
                        rotate: 'tangential',
                        formatter: function(value) {
                            if (value === 0.875) {
                                return '优'
                            } else if (value === 0.625) {
                                return '中'
                            } else if (value === 0.375) {
                                return '良'
                            } else if (value === 0.125) {
                                return '差'
                            }
                        }
                    },
                    title: {
                        offsetCenter: [0, '-50%'],
                        fontSize: 40
                    },
                    detail: {
                        valueAnimation: true,
                        fontSize: 50,
                        offsetCenter: [0, '-30%'],
                        formatter: function(value) {
                            return Math.round(value * 100) + '%';
                        },
                        color: 'auto'
                    },
                    data: [{
                        value: 0.75,
                        name: '成绩评定'
                    }]
                }]
            };

            var chart = testHelper.create(echarts, 'main3', {
                title: [
                    'Value animation should be enabled'
                ],
                option: option
            });
        });
    </script>
</body>

</html>
