| <!-- | |
| 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/jquery.min.js'></script> | |
| <meta name="viewport" content="width=device-width, initial-scale=1" /> | |
| </head> | |
| <body> | |
| <style> | |
| html, body, #main { | |
| width: 100%; | |
| height: 100%; | |
| margin: 0; | |
| } | |
| #next { | |
| position: absolute; | |
| left: 10px; | |
| top: 10px; | |
| } | |
| </style> | |
| <div id='main'></div> | |
| <button id="next">NEXT</button> | |
| <script> | |
| require([ | |
| 'echarts', | |
| 'data/usa.json' | |
| ], function (echarts, geojson) { | |
| echarts.registerMap('USA', geojson, { | |
| Alaska: { // 把阿拉斯加移到美国主大陆左下方 | |
| left: -131, | |
| top: 25, | |
| width: 15 | |
| }, | |
| Hawaii: { | |
| left: -110, // 夏威夷 | |
| top: 28, | |
| width: 5 | |
| }, | |
| 'Puerto Rico': { // 波多黎各 | |
| left: -76, | |
| top: 26, | |
| width: 2 | |
| } | |
| }); | |
| const tmpChart = echarts.init(document.createElement('div'), null, { | |
| width: window.innerWidth, | |
| height: window.innerHeight | |
| }); | |
| tmpChart.setOption({ | |
| geo: { | |
| map: 'USA' | |
| } | |
| }); | |
| const geo = tmpChart.getModel().getComponent('geo').coordinateSystem; | |
| const regionsMap = geo.regions.reduce(function (obj, region) { | |
| obj[region.properties.name] = region; | |
| return obj; | |
| }, {}); | |
| const transform = geo.transform; | |
| const data = [ | |
| {name: 'Alabama', value: 4822023}, | |
| {name: 'Alaska', value: 731449}, | |
| {name: 'Arizona', value: 6553255}, | |
| {name: 'Arkansas', value: 2949131}, | |
| {name: 'California', value: 38041430}, | |
| {name: 'Colorado', value: 5187582}, | |
| {name: 'Connecticut', value: 3590347}, | |
| {name: 'Delaware', value: 917092}, | |
| {name: 'District of Columbia', value: 632323}, | |
| {name: 'Florida', value: 19317568}, | |
| {name: 'Georgia', value: 9919945}, | |
| {name: 'Hawaii', value: 1392313}, | |
| {name: 'Idaho', value: 1595728}, | |
| {name: 'Illinois', value: 12875255}, | |
| {name: 'Indiana', value: 6537334}, | |
| {name: 'Iowa', value: 3074186}, | |
| {name: 'Kansas', value: 2885905}, | |
| {name: 'Kentucky', value: 4380415}, | |
| {name: 'Louisiana', value: 4601893}, | |
| {name: 'Maine', value: 1329192}, | |
| {name: 'Maryland', value: 5884563}, | |
| {name: 'Massachusetts', value: 6646144}, | |
| {name: 'Michigan', value: 9883360}, | |
| {name: 'Minnesota', value: 5379139}, | |
| {name: 'Mississippi', value: 2984926}, | |
| {name: 'Missouri', value: 6021988}, | |
| {name: 'Montana', value: 1005141}, | |
| {name: 'Nebraska', value: 1855525}, | |
| {name: 'Nevada', value: 2758931}, | |
| {name: 'New Hampshire', value: 1320718}, | |
| {name: 'New Jersey', value: 8864590}, | |
| {name: 'New Mexico', value: 2085538}, | |
| {name: 'New York', value: 19570261}, | |
| {name: 'North Carolina', value: 9752073}, | |
| {name: 'North Dakota', value: 699628}, | |
| {name: 'Ohio', value: 11544225}, | |
| {name: 'Oklahoma', value: 3814820}, | |
| {name: 'Oregon', value: 3899353}, | |
| {name: 'Pennsylvania', value: 12763536}, | |
| {name: 'Rhode Island', value: 1050292}, | |
| {name: 'South Carolina', value: 4723723}, | |
| {name: 'South Dakota', value: 833354}, | |
| {name: 'Tennessee', value: 6456243}, | |
| {name: 'Texas', value: 26059203}, | |
| {name: 'Utah', value: 2855287}, | |
| {name: 'Vermont', value: 626011}, | |
| {name: 'Virginia', value: 8185867}, | |
| {name: 'Washington', value: 6897012}, | |
| {name: 'West Virginia', value: 1855413}, | |
| {name: 'Wisconsin', value: 5726398}, | |
| {name: 'Wyoming', value: 576412}, | |
| {name: 'Puerto Rico', value: 3667084} | |
| ]; | |
| const myChart = echarts.init(document.getElementById('main')); | |
| function createMapOption() { | |
| return { | |
| series: [{ | |
| coordinateSystem: 'none', | |
| type: 'custom', | |
| data, | |
| animationDurationUpdate: 2000, | |
| universalTransition: { | |
| enabled: true | |
| }, | |
| renderItem(params, api) { | |
| const dataItem = data[params.dataIndex]; | |
| const geometries = regionsMap[dataItem.name].geometries.slice(); | |
| // Pick the main polygon | |
| // TODO Multipolygon | |
| geometries.sort((a, b) => b.exterior.length - a.exterior.length); | |
| const points = geometries[0].exterior; | |
| const newPoints = []; | |
| for (let i = 0; i < points.length; i++) { | |
| newPoints.push([ | |
| points[i][0] * transform[0] + transform[4], | |
| points[i][1] * transform[3] + transform[5] | |
| ]); | |
| } | |
| return { | |
| type: 'polygon', | |
| shape: { | |
| points: newPoints | |
| }, | |
| style: { | |
| fill: '#aaa', | |
| stroke: '#555', | |
| strokeNoScale: true | |
| } | |
| } | |
| } | |
| }] | |
| }; | |
| } | |
| function renderBarItem(params, api) { | |
| const dataItem = data[params.dataIndex]; | |
| const start = api.coord([params.dataIndex, 0]); | |
| const size = api.size([0, api.value(1)]); | |
| const width = 20; | |
| return { | |
| type: 'rect', | |
| shape: { | |
| x: start[0] - width / 2, | |
| y: start[1], | |
| width: width, | |
| height: -size[1] | |
| }, | |
| style: { | |
| fill: '#aaa', | |
| stroke: '#555', | |
| strokeNoScale: true | |
| }, | |
| }; | |
| } | |
| function renderBubbleItem(params, api) { | |
| const dataItem = data[params.dataIndex]; | |
| const center = api.coord([params.dataIndex, api.value(1)]); | |
| return { | |
| type: 'circle', | |
| shape: { | |
| cx: center[0], | |
| cy: center[1], | |
| r: api.value(1) / 5e5 | |
| }, | |
| style: { | |
| fill: '#aaa', | |
| stroke: '#555', | |
| strokeNoScale: true | |
| }, | |
| }; | |
| } | |
| function createCartesianOption(renderItem) { | |
| return { | |
| xAxis: { | |
| data: data.map(item => item.name) | |
| }, | |
| yAxis: { | |
| }, | |
| series: [{ | |
| type: 'custom', | |
| data, | |
| animationDurationUpdate: 2000, | |
| universalTransition: { | |
| enabled: true | |
| }, | |
| renderItem | |
| }] | |
| }; | |
| } | |
| function createPieOption(renderItem) { | |
| const pieData = data.slice(); | |
| pieData.reverse(); | |
| const totalValue = pieData.reduce(function (val, item) { | |
| return val + item.value; | |
| }, 0); | |
| let angles = []; | |
| let currentAngle = -Math.PI / 2; | |
| for (let i = 0; i < pieData.length; i++) { | |
| const angle = pieData[i].value / totalValue * Math.PI * 2; | |
| angles.push([currentAngle, angle + currentAngle]); | |
| currentAngle += angle; | |
| } | |
| return { | |
| series: [{ | |
| type: 'custom', | |
| coordinateSystem: 'none', | |
| data: pieData, | |
| animationDurationUpdate: 2000, | |
| universalTransition: { | |
| enabled: true | |
| }, | |
| renderItem(params, api) { | |
| const width = myChart.getWidth(); | |
| const height = myChart.getHeight(); | |
| return { | |
| type: 'sector', | |
| shape: { | |
| cx: width / 2, | |
| cy: height / 2, | |
| r: Math.min(width, height) / 3, | |
| r0: Math.min(width, height) / 5, | |
| startAngle: angles[params.dataIndex][0], | |
| endAngle: angles[params.dataIndex][1], | |
| clockwise: true | |
| }, | |
| style: { | |
| fill: '#aaa', | |
| stroke: '#555', | |
| strokeNoScale: true | |
| }, | |
| }; | |
| } | |
| }] | |
| }; | |
| } | |
| const options = [ | |
| createMapOption(), | |
| createCartesianOption(renderBarItem), | |
| createCartesianOption(renderBubbleItem), | |
| createPieOption() | |
| ]; | |
| let currentIndex = 0; | |
| myChart.setOption(options[currentIndex]); | |
| function transitionToNext() { | |
| const nextIndex = (currentIndex + 1) % options.length; | |
| myChart.setOption(options[nextIndex], true); | |
| currentIndex = nextIndex; | |
| } | |
| document.querySelector('#next').onclick = function () { | |
| transitionToNext(); | |
| } | |
| }); | |
| </script> | |
| </body> | |
| </html> |