<!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/esl.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'
                // 'echarts/chart/map',
                // 'echarts/chart/custom',
                // 'echarts/component/geo',
                // 'echarts/component/legend',
                // 'echarts/component/tooltip',
                // 'echarts/component/toolbox',
                // 'echarts/component/visualMap',
                // 'echarts/component/dataZoom'
            ], function (ec) {

                echarts = ec;

                $.get('./data/map/json/world.json', function (worldJson) {
                    echarts.registerMap('world', worldJson);

                    $.getJSON('./data/global-wind.json', function (windData) {
                        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>