
<!--
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>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <!-- <link href="https://fonts.googleapis.com/css2?family=Open+Sans+Condensed:wght@300&display=swap" rel="stylesheet"> -->
        <link href="https://fonts.googleapis.com/css2?family=Barlow+Condensed:wght@300&family=Open+Sans+Condensed:wght@300&display=swap" rel="stylesheet">
    </head>
    <body>
        <style>
            html, body {
                width: 100%;
                height: 100%;
            }
            html, body, #main {
                margin: 0;
                padding: 0;
            }
            #main {
                margin-top: 90px;
                position: absolute;
                left: 0;
                right: 0;
                bottom: 0;
                top: 0;
            }
            .controller {
                font-size: 14px;
                position: fixed;
                top: 0;
                left: 0;
                right: 0;
                background: #eee;
                border-bottom: 1px solid #ccc;
                line-height: 20px;
                z-index: 100;
            }
            .controller label {
                margin-right: 10px;
            }
            .item-title {
                font-weight: bold;
            }
            .controller .mode-title {
                float: left;
                width: 60px;
                vertical-align: middle;
                padding-left: 10px;
            }
            .controller .mode-body {
                float: left;
                width: 700px;
            }
            .controller .query {
                margin-left: 800px;
                padding-top: 10px;
            }
            .controller .query #query-input {
                width: 250px;
            }
            .tooltip-title {
                color: yellow;
                font-size: 16px;
                margin-bottom: 5px;
            }
        </style>
        <div class="controller">
            <div class="mode-title">示例模式<br>(Mode)</div>
            <div class="mode-body">
                <input type="radio" id="area-meaning-0" name="area-meaning" onclick="areaMeasureChange(0);" checked="checked"/>
                <label for="area-meaning-0">面积代表“2012年预算额” (Area represents '2012 Amount)</label><br>
                <input type="radio" id="area-meaning-2" name="area-meaning" onclick="areaMeasureChange(2);"/>
                <label for="area-meaning-2">面积代表“2012年预算额”，明暗代表“2011年相比的增长率”<br>&nbsp;&nbsp;&nbsp;&nbsp; (Area represents '2012 Amount' and color-alpha represents 'Change from 2011')</label><br>
                <input type="radio" id="area-meaning-1" name="area-meaning" onclick="areaMeasureChange(1);"/>
                <label for="area-meaning-1">面积代表“2011年预算额” (Area represents '2011 Amount')</label>
            </div>
            <div class="query">
                <input id="query-input" type="text" placeholder="请输入节点名 (Please node name)" onkeypress="if (event.keyCode === 13) { query(); return false; }"/>
                <input type="button" class="query-btn" value="检索节点(query)" onclick="query();" />
            </div>
        </div>
        <div id="main"></div>

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

        <script>

            var chart;
            var formatUtil;

            var SERIES_NAME = 'Obama’s 2012 Budget Proposal: How $3.7 Trillion is Spent';

            require([
                'echarts'
            ], init);

            function areaMeasureChange(mode) {
                chart.setOption({
                    tooltip: {
                        formatter: getTooltipFormatter(mode)
                    },
                    series: [{
                        visualDimension: mode === 2 ? 2 : null,
                        data: buildData(mode, window.obama_budget_2012),
                        levels: getLevelOption(mode)
                    }]
                });
            }

            function query() {
                var nodeName = document.getElementById('query-input').value;
                // 先找精确匹配的
                var nodeIdList = findNodeId(nodeName, window.obama_budget_2012);
                // 再找模糊匹配的
                if (!nodeIdList.length) {
                    nodeIdList = findNodeId(nodeName, window.obama_budget_2012, true);
                }

                if (nodeIdList.length) {
                    // FIXME
                    // 接口？
                    chart.dispatchAction({
                        type: 'treemapZoomToNode',
                        seriesName: SERIES_NAME,
                        // 这个示例中简单处理，只聚焦到找到的第一个节点上。
                        targetNodeId: nodeIdList[0]
                    });
                }
                else {
                    alert('没有找到节点 (No result)');
                }
            }

            function findNodeId(nodeName, originList, fuzzy) {
                var out = [];
                nodeName = nodeName.toLowerCase();

                for (var i = 0, len = originList.length; i < len; i++) {
                    var node = originList[i];
                    if (node.name
                        && (
                            fuzzy
                            ? node.name.toLowerCase().indexOf(nodeName) === 0
                            : node.name.toLowerCase() === nodeName
                        )
                    ) {
                        out.push(node.id);
                    }
                    if (node.children) {
                        out.push.apply(out, findNodeId(nodeName, node.children, fuzzy));
                    }
                }

                return out;
            }

            function buildData(mode, originList) {
                var out = [];

                for (var i = 0; i < originList.length; i++) {
                    var node = originList[i];
                    var newNode = out[i] = cloneNodeInfo(node);
                    var value = newNode.value;

                    if (!newNode) {
                        continue;
                    }

                    // Calculate amount per household.
                    value[3] = value[0] / window.household_america_2012;

                    // if mode === 0 and mode === 2 do nothing
                    if (mode === 1) {
                        // Set 'Change from 2010' to value[0].
                        var tmp = value[1];
                        value[1] = value[0];
                        value[0] = tmp;
                    }

                    if (node.children) {
                        newNode.children = buildData(mode, node.children);
                    }
                }

                return out;
            }

            function cloneNodeInfo(node) {
                if (!node) {
                    return;
                }

                var newNode = {};
                newNode.name = node.name;
                newNode.id = node.id;
                newNode.discretion = node.discretion;
                newNode.value = (node.value || []).slice();
                return newNode;
            }

            function getLevelOption(mode) {
                return [
                    {
                        color: mode === 2
                            ? [
                                '#5793f3', '#d14a61', '#fd9c35',
                                '#675bba', '#fec42c', '#dd4444',
                                '#d4df5a', '#cd4870'
                            ]
                            : null,
                        colorMappingBy: 'id',
                        itemStyle: {
                            borderWidth: 3,
                            gapWidth: 3,
                            borderRadius: 5,
                            shadowBlur: 20,
                            shadowColor: 'rgba(20, 20, 40, 1)',
                        }
                    },
                    {
                        colorAlpha: mode === 2
                            ? [0.3, 0.5] : null,
                        itemStyle: {
                            borderWidth: 2,
                            gapWidth: 1,
                            borderRadius: 5,
                            shadowBlur: 5,
                            shadowColor: 'rgba(20, 20, 40, 0.5)'
                        }
                    },
                    {
                        upperLabel: {
                            show: false
                        },
                        itemStyle: {
                            borderWidth: 0,
                            gapWidth: 0,
                            borderRadius: 1
                        }
                    }
                ];
            }

            function isValidNumber(num) {
                return num != null && isFinite(num);
            }

            function getTooltipFormatter(mode) {
                var amountIndex = mode === 1 ? 1 : 0;
                var amountIndex2011 = mode === 1 ? 0 : 1;

                return function (info) {
                    var value = info.value;

                    var amount = value[amountIndex];
                    amount = isValidNumber(amount)
                        ? formatUtil.addCommas(amount * 1000) + '$'
                        : '-';

                    var amount2011 = value[amountIndex2011];
                    amount2011 = isValidNumber(amount2011)
                        ? formatUtil.addCommas(amount2011 * 1000) + '$'
                        : '-';

                    var perHousehold = value[3];
                    perHousehold = isValidNumber(perHousehold)
                        ? formatUtil.addCommas((+perHousehold.toFixed(4)) * 1000) + '$'
                        : '-';

                    var change = value[2];
                    change = isValidNumber(change)
                        ? change.toFixed(2) + '%'
                        : '-';

                    return [
                        '<div class="tooltip-title">' + formatUtil.encodeHTML(info.name) + '</div>',
                        '2012 Amount: &nbsp;&nbsp;' + amount + '<br>',
                        'Per Household: &nbsp;&nbsp;' + perHousehold + '<br>',
                        '2011 Amount: &nbsp;&nbsp;' + amount2011 + '<br>',
                        'Change From 2011: &nbsp;&nbsp;' + change
                    ].join('');
                }
            }

            function init(echarts) {

                formatUtil = echarts.format;

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

                });

                chart.setOption({
                    // backgroundColor: '#000',

                    legend: {
                        data: [SERIES_NAME]
                    },

                    tooltip: {
                        formatter: getTooltipFormatter(0)
                    },

                    series: [
                        {
                            name: SERIES_NAME,
                            type: 'treemap',
                            top: 50,
                            bottom: 80,
                            label: {
                                show: true,
                                formatter: "{b}",
                                fontSize: 10,
                                fontWeight: 100,
                                fontFamily: 'Barlow Condensed',
                                overflow: 'break'
                            },
                            labelLayout: function (params) {
                                if (params.rect.width < 5 || params.rect.height < 5) {
                                    return {
                                        fontSize: 0
                                    };
                                }
                                return {
                                    fontSize: Math.min(Math.sqrt(params.rect.width * params.rect.height) / 10, 20)
                                };
                            },
                            itemStyle: {
                                borderColor: 'rgba(100, 100, 200, 0.2)',
                                borderWidth: 0
                            },
                            upperLabel: {
                                show: true,
                                height: 15,
                                fontSize: 10,
                                fontFamily: 'Barlow Condensed',
                                color: null
                            },
                            levels: getLevelOption(0),
                            data: buildData('2012 Amount', window.obama_budget_2012)
                        }
                    ]
                });
            }

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