|  |  | 
|  | <!-- | 
|  | 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> |