
<!--
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/testHelper.js"></script>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
    </head>
    <body>
        <style>
            html, body, #main {
                width: 100%;
                height: 100%;
                margin: 0;
                padding: 0;
            }
            .controller {
                position: fixed;
                top: 0;
                left: 0;
                right: 0;
                background: #fff;
                border-bottom: 1px solid #ccc;
                line-height: 30px;
                z-index: 100;
            }
            .controller label {
                margin-right: 10px;
            }
            .item-title {
                font-weight: bold;
            }
            .controller .item {
                margin-right: 20px;
                padding-right: 10px;
                border-right: 1px solid #ccc;
            }
            .tooltip-title {
                color: yellow;
                font-size: 16px;
                margin-bottom: 5px;
            }
            #btn-area {
                position: fixed;
                left: 10px;
                top: 10px;
                z-index: 999999;
                background-color: #fff;
            }
        </style>

        <div id="btn-area">
        </div>

        <div id="main"></div>

        <script src="data/disk.tree.js"></script>

        <script>

            var chart;
            var formatUtil;

            require([
                'echarts'
            ], function (echarts) {
                formatUtil = echarts.format;
                initEcharts(echarts);
            });

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

                });

                chart.setOption({

                    tooltip: {
                        formatter: function (info) {
                            var value = info.value;
                            var treePathInfo = info.treePathInfo;
                            var treePath = [];

                            for (var i = 1; i < treePathInfo.length; i++) {
                                treePath.push(treePathInfo[i].name);
                            }

                            return [
                                '<div class="tooltip-title">' + formatUtil.encodeHTML(treePath.join('/')) + '</div>',
                                'Disk Usage: ' + formatUtil.addCommas(value) + ' KB',
                            ].join('');
                        }
                    },

                    series: [
                        {
                            name:'Disk Usage',
                            type:'treemap',
                            visibleMin: 300,
                            upperLabel: {
                                normal: {
                                    show: true,
                                    height: 30,
                                    color: 'green'
                                }
                            },
                            itemStyle: {
                                normal: {
                                    // borderColor: '#fff'
                                },
                                emphasis: {
                                    strokeColor: 'yellow',
                                    strokeWidth: 2
                                }
                            },
                            levels: [
                                {
                                    color: ['#d14a61'], // default color
                                    itemStyle: {
                                        normal: {
                                            borderWidth: 5,
                                            gapWidth: 3
                                        },
                                        emphasis: {
                                            borderColor: 'red'
                                        }
                                    },
                                },
                                {
                                    color: [
                                        '#d14a61', '#fd9c35',
                                        '#675bba', '#fec42c', '#dd4444',
                                        '#d4df5a', '#cd4870'
                                    ],
                                    highDownTarget: 'subtree',
                                    colorMappingBy: 'value',
                                    itemStyle: {
                                        normal: {
                                            borderColor: '#aaa',
                                            borderWidth: 5,
                                            gapWidth: 3
                                        },
                                        emphasis: {
                                            borderColor: 'red'
                                        }
                                    }
                                },
                                {
                                    colorSaturation: [0.35, 0.5],
                                    itemStyle: {
                                        normal: {
                                            borderWidth: 5,
                                            gapWidth: 3,
                                            borderColorSaturation: 0.6
                                        }
                                    }
                                }
                            ],
                            data: window.disk_usage_tree
                        }
                    ]
                });

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

                initBtns('Only single bg highlighted for non-leaf', [
                    'Disk Usage',
                    'PrivateFrameworks'
                ]);
                initBtns('Both of the bg and content is highlighted for leaf', [
                    'Alex.SpeechVoice'
                ]);

                function initBtns(desc, names) {
                    var btnArea = document.getElementById('btn-area');

                    var descEl = document.createElement('span');
                    descEl.innerHTML = testHelper.encodeHTML(desc) + '&nbsp;:&nbsp;&nbsp;';
                    btnArea.appendChild(descEl);

                    var highDown = ['highlight', 'downplay'];

                    for (var i = 0; i < names.length; i++) {
                        for (var j = 0; j < highDown.length; j++) {
                            var highDownName = highDown[j];
                            var name = names[i];
                            var btnEl = document.createElement('button');
                            btnEl.innerHTML = testHelper.encodeHTML(highDownName + ': ' + name);
                            btnEl.onclick = echarts.util.curry(clickHandler, highDownName, name);
                            btnArea.appendChild(btnEl);
                        }
                    }

                    function clickHandler(highDownName, name) {
                        chart.dispatchAction({
                            type: highDownName,
                            seriesIndex: 0,
                            name: name
                        });
                    }

                    btnArea.appendChild(document.createElement('br'));
                }
            }

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