|  | 
 | <!-- | 
 | 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>     (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:   ' + amount + '<br>', | 
 |                         'Per Household:   ' + perHousehold + '<br>', | 
 |                         '2011 Amount:   ' + amount2011 + '<br>', | 
 |                         'Change From 2011:   ' + 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> |