<!DOCTYPE html>
<!--
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">
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <script src="lib/simpleRequire.js"></script>
        <script src="lib/config.js"></script>
        <script src="lib/jquery.min.js"></script>
        <script src="lib/facePrint.js"></script>
        <script src="lib/testHelper.js"></script>
        <link rel="stylesheet" href="lib/reset.css">
    </head>
    <body>
        <style>
            h1 {
                line-height: 60px;
                height: 60px;
                background: #146402;
                text-align: center;
                font-weight: bold;
                color: #eee;
                font-size: 14px;
            }
            .chart {
                height: 500px;
            }
        </style>


        <div class="chart" id="main"></div>




        <script>

            var echarts;
            var chart;
            var myChart;
            var groupCategories = [];
            var groupColors = [];

            require([
                'echarts',
                './data/map/json/world.json',
                './data/global-wind.json'
            ], function (ec, worldJson, windData) {

                echarts = ec;
                echarts.registerMap('world', worldJson);
                var p = 0;
                var maxMag = 0;
                var minMag = Infinity;
                var data = [];
                for (var j = 0; j < windData.ny; j++) {
                    for (var i = 0; i < windData.nx; i++, p++) {
                        var vx = windData.data[p][0];
                        var vy = windData.data[p][1];
                        var mag = Math.sqrt(vx * vx + vy * vy);
                        // 数据是一个一维数组
                        // [ [经度, 维度，向量经度方向的值，向量维度方向的值] ]
                        data.push([
                            i / windData.nx * 360 - 180,
                            j / windData.ny * 180 - 90,
                            vx,
                            vy,
                            mag
                        ]);
                        maxMag = Math.max(mag, maxMag);
                        minMag = Math.min(mag, minMag);
                    }
                }
                data.reverse();

                var option = {
                    backgroundColor: '#333',
                    visualMap: {
                        left: 'center',
                        min: minMag,
                        max: maxMag,
                        dimension: 4,
                        inRange: {
                            // color: ['green', 'yellow', 'red']
                                    color: ['#313695', '#4575b4', '#74add1', '#abd9e9', '#e0f3f8', '#ffffbf', '#fee090', '#fdae61', '#f46d43', '#d73027', '#a50026']
                        },
                        realtime: false,
                        hoverLink: true,
                        calculable: true,
                        textStyle: {
                            color: '#fff'
                        },
                        orient: 'horizontal'
                    },
                    geo: {
                        map: 'world',
                        left: 0,
                        right: 0,
                        top: 0,
                        zoom: 1,
                        silent: true,
                        itemStyle: {
                            normal: {
                                areaColor: '#323c48',
                                borderColor: '#111'
                            }
                        }
                    },
                    series: {
                        type: 'custom',
                        coordinateSystem: 'geo',
                        data: data,
                        // silent: true,
                        encode: {
                            x: 0,
                            y: 0
                        },
                        renderItem: function (params, api) {
                            var x = api.value(0), y = api.value(1), dx = api.value(2), dy = api.value(3);
                            var start = api.coord([Math.max(x - dx / 5, -180), Math.max(y - dy / 5, -90)]);
                            var end = api.coord([Math.min(x + dx / 5, 180), Math.min(y + dy / 5, 90)]);
                            return {
                                type: 'line',
                                shape: {
                                    x1: start[0], y1: start[1],
                                    x2: end[0], y2: end[1]
                                },
                                style: {
                                    lineWidth: 0.5,
                                    stroke: api.visual('color')
                                }
                            }
                        },
                        progressive: 2000
                    }
                };

                testHelper.createChart(echarts, 'main', option);
            });
        </script>
    </body>
</html>