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



        <h1>Hexagonal Binning</h1>
        <div class="chart" id="hexagonal-binning"></div>




        <script>
            // Hexbin statistics code based on [d3-hexbin](https://github.com/d3/d3-hexbin)
            function hexBinStatistics(points, r) {
                var dx = r * 2 * Math.sin(Math.PI / 3)
                var dy = r * 1.5;
                var binsById = {};
                var bins = [];

                for (var i = 0, n = points.length; i < n; ++i) {
                    var point = points[i];
                    var px = point[0];
                    var py = point[1];

                    if (isNaN(px) || isNaN(py)) {
                        continue;
                    }

                    var pj = Math.round(py = py / dy);
                    var pi = Math.round(px = px / dx - (pj & 1) / 2);
                    var py1 = py - pj;

                    if (Math.abs(py1) * 3 > 1) {
                        var px1 = px - pi;
                        var pi2 = pi + (px < pi ? -1 : 1) / 2;
                        var pj2 = pj + (py < pj ? -1 : 1);
                        var px2 = px - pi2;
                        var py2 = py - pj2;
                        if (px1 * px1 + py1 * py1 > px2 * px2 + py2 * py2) {
                            pi = pi2 + (pj & 1 ? 1 : -1) / 2;
                            pj = pj2;
                        }
                    }

                    var id = pi + "-" + pj;
                    var bin = binsById[id];
                    if (bin) {
                        bin.points.push(point);
                    }
                    else {
                        bins.push(bin = binsById[id] = {points: [point]});
                        bin.x = (pi + (pj & 1) / 2) * dx;
                        bin.y = pj * dy;
                    }
                }

                var maxBinLen = -Infinity
                for (var i = 0; i < bins.length; i++) {
                    maxBinLen = Math.max(maxBinLen, bins.length);
                }

                return {
                    maxBinLen: maxBinLen,
                    bins: bins
                };
            }

        </script>


        <script>
            require([
                'echarts'
                // 'echarts/chart/custom',
                // 'echarts/chart/bar',
                // 'echarts/component/title',
                // 'echarts/component/geo',
                // 'echarts/component/legend',
                // 'echarts/component/tooltip',
                // 'echarts/component/visualMap',
                // 'echarts/component/dataZoom',
                // 'zrender/vml/vml'
            ], function (echarts) {

                // 2006-2007 Regular Season

                $.getJSON('./data/kawhi-leonard-16-17-regular.json', function (shotData) {
                    $.getJSON('./data/nba-court.json', function (nbaCourt) {

                        echarts.registerMap('nbaCourt', nbaCourt.borderGeoJSON);

                        var backgroundColor = '#333';
                        var hexagonRadiusInGeo = 1;

                        var hexBinResult = hexBinStatistics(
                            echarts.util.map(shotData.data, function (item) {
                                // "shot_made_flag" made missed
                                var made = item[echarts.util.indexOf(shotData.schema, 'shot_made_flag')];
                                return [
                                    item[echarts.util.indexOf(shotData.schema, 'loc_x')],
                                    item[echarts.util.indexOf(shotData.schema, 'loc_y')],
                                    made === 'made' ? 1 : 0
                                ];
                            }),
                            hexagonRadiusInGeo
                        );

                        var data = echarts.util.map(hexBinResult.bins, function (bin) {
                            var made = 0;
                            echarts.util.each(bin.points, function (point) {
                                made += point[2];
                            });
                            return [bin.x, bin.y, bin.points.length, (made / bin.points.length * 100).toFixed(2)];
                        });

                        function createItemRenderer(type) {
                            type = type || 'polygon';
                            return function renderItemHexBin(params, api) {
                                var center = api.coord([api.value(0), api.value(1)]);
                                var points = [];
                                var pointsBG = [];

                                var maxViewRadius = api.size([hexagonRadiusInGeo, 0])[0];
                                var minViewRadius = Math.min(maxViewRadius, 4);
                                var extentMax = Math.log(Math.sqrt(hexBinResult.maxBinLen));
                                var viewRadius = echarts.number.linearMap(
                                    Math.log(Math.sqrt(api.value(2))),
                                    [0, extentMax],
                                    [minViewRadius, maxViewRadius]
                                );

                                var angle = Math.PI / 6;
                                for (var i = 0; i < 6; i++, angle += Math.PI / 3) {
                                    points.push([
                                        center[0] + viewRadius * Math.cos(angle),
                                        center[1] + viewRadius * Math.sin(angle)
                                    ]);
                                    pointsBG.push([
                                        center[0] + maxViewRadius * Math.cos(angle),
                                        center[1] + maxViewRadius * Math.sin(angle)
                                    ]);
                                }

                                return {
                                    type: 'group',
                                    children: [{
                                        type,
                                        morph: true,
                                        shape: type === 'polygon' ? {
                                            points: points
                                        } : {
                                            // Circle
                                            cx: center[0],
                                            cy: center[1],
                                            r: viewRadius
                                        },
                                        style: {
                                            stroke: '#ccc',
                                            fill: api.visual('color'),
                                            lineWidth: 0
                                        }
                                    }, {
                                        type,
                                        morph: true,
                                        shape: type === 'polygon' ? {
                                            points: pointsBG
                                        } : {
                                            // Circle
                                            cx: center[0],
                                            cy: center[1],
                                            r: maxViewRadius
                                        },
                                        style: {
                                            stroke: null,
                                            fill: 'rgba(0,0,0,0.5)',
                                            lineWidth: 0
                                        },
                                        z2: -19
                                    }]
                                };
                            };
                        }

                        function renderItemNBACourt(param, api) {
                            return {
                                type: 'group',
                                children: echarts.util.map(nbaCourt.geometry, function (item) {
                                    return {
                                        type: item.type,
                                        style: {
                                            stroke: '#aaa',
                                            fill: null,
                                            lineWidth: 1.5
                                        },
                                        shape: {
                                            points: echarts.util.map(item.points, api.coord)
                                        }
                                    };
                                })
                            };
                        }

                        var option = {
                            backgroundColor: backgroundColor,
                            aria: {
                                show: true
                            },
                            tooltip: {
                                backgroundColor: 'rgba(255,255,255,0.9)',
                                textStyle: {
                                    color: '#333'
                                }
                            },
                            title: {
                                text: 'Kawhi Leonard',
                                subtext: '2016-2017 Regular Season',
                                backgroundColor: backgroundColor,
                                top: 10,
                                left: 10,
                                textStyle: {
                                    color: '#eee'
                                }
                            },
                            legend: {
                                data: ['bar', 'error']
                            },
                            geo: {
                                left: 0,
                                right: 0,
                                top: 0,
                                bottom: 0,
                                roam: true,
                                silent: true,
                                itemStyle: {
                                    normal: {
                                        color: backgroundColor,
                                        borderWidth: 0
                                    }
                                },
                                map: 'nbaCourt'
                            },
                            visualMap: {
                                type: 'continuous',
                                orient: 'horizontal',
                                right: 30,
                                top: 40,
                                min: 0,
                                max: 100,
                                align: 'bottom',
                                text: [null, 'FG:   '],
                                dimension: 3,
                                seriesIndex: 0,
                                calculable: true,
                                textStyle: {
                                    color: '#eee'
                                },
                                formatter: '{value} %',
                                inRange: {
                                    // color: ['rgba(241,222,158, 0.3)', 'rgba(241,222,158, 1)']
                                    color: ['green', 'yellow']
                                }
                            },
                            series: [{
                                type: 'custom',
                                coordinateSystem: 'geo',
                                geoIndex: 0,
                                renderItem: createItemRenderer(),
                                dimensions: [null, null, 'Field Goals Attempted (hexagon size)', 'Field Goal Percentage (color)'],
                                encode: {
                                    tooltip: [2, 3]
                                },
                                data: data
                            }, {
                                coordinateSystem: 'geo',
                                type: 'custom',
                                geoIndex: 0,
                                renderItem: renderItemNBACourt,
                                silent: true,
                                data: [0]
                            }]
                        };

                        // var width = 1000;
                        const myChart = testHelper.create(echarts, 'hexagonal-binning', {
                            option,
                            buttons: [{
                                text: 'Hexgon',
                                onClick: function() {
                                    myChart.setOption({
                                        series: [{
                                            type: 'custom',
                                            renderItem: createItemRenderer('polygon')
                                        }]
                                    });
                                }
                            }, {
                                text: 'Circle',
                                onClick: function() {
                                    myChart.setOption({
                                        series: [{
                                            type: 'custom',
                                            renderItem: createItemRenderer('circle')
                                        }]
                                    });
                                }
                            }]
                            // width: width,
                            // height: width * nbaCourt.height / nbaCourt.width
                        });
                    });
                });
            });
        </script>








    </body>
</html>