
<!--
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>
    </head>
    <body>
        <style>
            html, body, #main {
                width: 100%;
                height: 100%;
                /* background-image: url(old_mathematics.png); */
                /* background-repeat: repeat; */
            }
        </style>
        <div id="main"></div>
        <script>
            var chart;
            require([
                'echarts'
            ], function (echarts) {

                chart = echarts.init(document.getElementById('main'), null, {
                    // renderer: 'svg'
                });

                var data = [{
                    name: 'Grandpa',
                    children: [{
                        name: 'Uncle Leo',
                        value: 15,
                        children: [{
                            name: 'Cousin Jack',
                            value: 2
                        }, {
                            name: 'Cousin Mary',
                            value: 5,
                            children: [{
                                name: 'Jackson',
                                value: 2
                            }]
                        }, {
                            name: 'Cousin Ben',
                            value: 4
                        }]
                    }, {
                        name: 'Aunt Jane',
                        children: [{
                            name: 'Cousin Kate',
                            value: 4
                        }]
                    }, {
                        name: 'Father',
                        value: 10,
                        children: [{
                            name: 'Me',
                            value: 5,
                            itemStyle: {
                                color: 'red'
                            }
                        }, {
                            name: 'Brother Peter',
                            value: 1
                        }]
                    }]
                }, {
                    name: 'Mike',
                    children: [{
                        name: 'Uncle Dan',
                        children: [{
                            name: 'Cousin Lucy',
                            value: 3
                        }, {
                            name: 'Cousin Luck',
                            value: 4,
                            children: [{
                                name: 'Nephew',
                                value: 2
                            }]
                        }]
                    }]
                }, {
                    name: 'Nancy',
                    children: [{
                        name: 'Uncle Nike',
                        children: [{
                            name: 'Cousin Betty',
                            value: 1
                        }, {
                            name: 'Cousin Jenny',
                            value: 2
                        }]
                    }]
                }];

                chart.setOption({
                    visualMap: {
                        type: 'continuous',
                        min: 0,
                        max: 10,
                        inRange: {
                            color: ['#2D5F73', '#538EA6', '#F2D1B3', '#F2B8A2', '#F28C8C']
                        }
                    },
                    series: {
                        type: 'sunburst',
                        data: data,
                        radius: [0, '90%'],
                        label: {
                            rotate: 'radial'
                        },
                        levels: [{}, {
                            label: {
                                formatter: function (params) {
                                    return 'First Level\n' + params.name;
                                }
                            },
                            emphasis: {
                                label: {
                                    formatter: function (params) {
                                        return 'emphasis\n' + params.name;
                                    }
                                }
                            }
                        }, {
                            downplay: {
                                label: {
                                    formatter: function (params) {
                                        return 'downplay\n' + params.name;
                                    }
                                }
                            }
                        }]
                    }
                });

                setTimeout(function () {
                    chart.dispatchAction({
                        type: 'sunburstHighlight',
                        targetNodeId: 'Cousin Jenny'
                    });
                }, 3000);

                setTimeout(function () {
                    chart.dispatchAction({
                        type: 'sunburstUnhighlight'
                    });
                }, 5000);
            });

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