<!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" />
        <link rel="stylesheet" href="lib/reset.css" />
        <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>
        <script src="https://api.map.baidu.com/api?v=3.0&ak=KOmVjPVUAey1G2E8zNhPiuQ6QiEmAwZu&__ec_v__=20200330"></script>
        <!-- <script src="https://www.echartsjs.com/examples/vendors/echarts/extension/bmap.js?_ec_v__=20200330"></script> -->
    </head>
    <body>
        <div id="main0"></div>
        <div id="main1"></div>

        <script>
            require([
                'echarts', 'extension/bmap'
            ], function (echarts) {
                var symbolIcon = 'data:image/png;base64,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';
                var option = {
                    bmap: {
                        center: [116, 31],
                        zoom: 7,
                        roam: true
                    },
                    series: [{
                        coordinateSystem: 'bmap',
                        symbol: 'image://' + symbolIcon,
                        symbolSize: [15, 30],
                        symbolRotate: function(value, params) {
                            return -value[2]
                        },
                        label: {
                            show: true,
                            position: 'top',
                            distance: 15,
                            formatter: function(params) {
                                return params.name + '(' + params.value[2] + 'deg)'
                            },
                            verticalAlign: 'middle',
                            align: 'center',
                            borderWidth: 1.25,
                            borderRadius: 2,
                            borderColor: '#14c4ba',
                            backgroundColor: '#fff',
                            padding: [5, 8, 3, 8],
                            color: '#000'
                        },
                        data: [
                            {
                                name: 'car1',
                                value: [121.15, 31.89, 30]
                            },
                            {
                                name: 'car2',
                                value: [117.781327, 32.608266, 120]
                            },
                            {
                                name: 'car3',
                                value: [117.5, 30.608266, 90]
                            },
                            {
                                name: 'car4',
                                value: [115.5, 30.2, 180]
                            }
                        ],
                        encode: {
                            value: 2
                        },
                        type: 'scatter'
                    }]
                };

                var series = {
                    name: 'Original',
                    type: 'scatter',
                    symbol: 'circle',
                    data: (function() {
                        function random(max) {
                            return +(Math.random() * max).toFixed(3);
                        }
                        var seriesData = [];
                        for (var i = 0; i < 20; i++) {
                            seriesData.push([random(10), random(10), random(20)]);
                        }
                        return seriesData;
                    })()
                };

                var option2 = {
                    legend: {},
                    xAxis: {},
                    yAxis: {},
                    tooltip: {
                        formatter: function(params) {
                            return params.marker + params.seriesName
                                + (params.seriesName === 'Offset' ? '<br/>offset: ' + params.value[2] : '');
                        }
                    },
                    series: [
                        series,
                        Object.assign({}, series, {
                            name: 'Offset',
                            symbol: 'circle',
                            // symbolOffset: 20,
                            symbolOffset: function(data) {
                                return data[2]
                            }
                        })
                    ]
                };

                var chart = testHelper.create(echarts, 'main0', {
                    title: 'Rotates the symbol as we need',
                    option: option
                });
                var chart2 = testHelper.create(echarts, 'main1', {
                    title: 'Symbol should have various offset',
                    option: option2
                });
            });
        </script>

    </body>
</html>
