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