
<!--
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,
                            itemStyle: {
                                opacity: 0.2
                            },
                            children: [{
                                name: 'Jackson',
                                value: 2
                            }]
                        }, {
                            name: 'Cousin Ben',
                            value: 4
                        }],
                        itemStyle: {
                            color: '#660'
                        }
                    }, {
                        name: 'Aunt Jane',
                        children: [{
                            name: 'Cousin Kate',
                            value: 4,
                            itemStyle: {
                                color: '#660'
                            }
                        }]
                    }, {
                        name: 'Father',
                        value: 10,
                        children: [{
                            name: 'Me',
                            value: 5
                        }, {
                            name: 'Brother Peter',
                            value: 1
                        }],
                        itemStyle: {
                            downplay: {
                                opacity: 0.1
                            }
                        }
                    }],
                    itemStyle: {
                        downplay: {
                            opacity: 0.8
                        }
                    }
                }, {
                    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({
                    tooltip: {
                        trigger: 'item'
                    },
                    aria: {
                        show: true
                    },
                    series: {
                        type: 'sunburst',
                        // highlightPolicy: 'ancestor',
                        data: data,
                        radius: [0, '90%'],
                        label: {
                            rotate: 'radial'
                        },
                        levels: [{
                            itemStyle: {
                                opacity: 1,
                                color: '#70d'
                            }
                        }, {
                            itemStyle: {
                                opacity: 0.8,
                                color: '#f0f'
                            },
                            label: {
                                opacity: 0.8,
                                formatter: '{a}: {b}'
                            }
                        }, {
                            itemStyle: {
                                opacity: 0.6,
                                color: '#00f'
                            },
                            label: {
                                opacity: 0.6
                            }
                        }, {
                            itemStyle: {
                                opacity: 0.4
                            }
                        }]
                    }
                });

                setTimeout(function () {
                    data.push({
                        name: 'Stranger',
                        children: [{
                            name: 'S1',
                            value: 4
                        }, {
                            name: 'S2',
                            value: 1
                        }]
                    });
                    chart.setOption({
                        series: {
                            data: data
                        }
                    });
                }, 3000);

                setTimeout(function () {
                    data.splice(1, 1);
                    data[0].value = 32;
                    chart.setOption({
                        series: {
                            data: data
                        }
                    });
                }, 6000);

            });

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