99Echarts - 地理坐标/地图(Hexagonal Binning)

简介: 99Echarts - 地理坐标/地图(Hexagonal Binning)
效果图

源代码
// 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
    };
}
$.when(
    $.getJSON('data/asset/data/kawhi-leonard-16-17-regular.json'),
    $.getJSON('data/asset/data/nba-court.json')
).done(function (shotData, nbaCourt) {
    shotData = shotData[0];
    nbaCourt = nbaCourt[0];
    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 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: 'polygon',
                shape: {
                    points: points
                },
                style: {
                    stroke: '#ccc',
                    fill: api.visual('color'),
                    lineWidth: 1
                }
            }, {
                type: 'polygon',
                shape: {
                    points: pointsBG
                },
                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)
                    }
                };
            })
        };
    }
    option = {
        backgroundColor: backgroundColor,
        tooltip: {
            backgroundColor: 'rgba(255,255,255,0.9)',
            textStyle: {
                color: '#333'
            }
        },
        animation: false,
        title: {
            text: 'Kawhi Leonard',
            subtext: '2016-2017 NBA 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,
            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: renderItemHexBin,
            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]
        }]
    };
    myChart.setOption(option);
    // var width = 700;
    // testHelper.createChart(echarts, 'hexagonal-binning', option, {
    //     width: width,
    //     height: width * nbaCourt.height / nbaCourt.width
    // });
});
目录
相关文章
|
4天前
|
JSON 数据可视化 JavaScript
Echarts地图实现:山东省会员活跃度
使用ECharts展示山东会员活跃度,通过散点图和地图结合,颜色对比强烈,背景深蓝(#020933)、点色明亮黄(#F4E925)。核心代码示例展示了散点、地图及特效散点系列配置。[点击下载](https://download.csdn.net/download/No_Name_Cao_Ni_Mei/89493130)代码和数据。
5 0
Echarts地图实现:山东省会员活跃度
|
4天前
|
JSON JavaScript 前端开发
Echarts地图实现:杭州市困难人数分布
使用ECharts实现杭州困难人数分布地图,结合地区与散点图,动态展示数据变化。支持进入下级区域并返回。预览包含动画效果。关键代码涉及地图初始化、数据加载及事件处理。需`hangzhou-map.json`数据文件。完整代码和资源见链接。
13 0
Echarts地图实现:杭州市困难人数分布
|
7天前
|
JSON JavaScript 定位技术
Echarts自定义地图显示区域,可以显示街道,小区,学校等区域
Echarts自定义地图显示区域,可以显示街道,小区,学校等区域
|
7天前
|
JSON JavaScript 定位技术
Echarts 绘制地图(中国、省市、区县),保姆级教程!
Echarts 绘制地图(中国、省市、区县),保姆级教程!
|
2月前
|
定位技术
echarts 地图点位
在使用ECharts的点击事件绑定中,观察到每次点击会递增一次后台请求:首次点击请求1次,第二次点击请求2次,第三次点击请求3次,以此类推。为解决这个问题,尝试在事件绑定前使用`myChart.off(&#39;click&#39;)`移除原有监听器,然后添加新的点击事件处理函数。
25 0
|
2月前
|
数据采集 JSON 数据可视化
python_selenuim获取csdn新星赛道选手所在城市用echarts地图显示
python_selenuim获取csdn新星赛道选手所在城市用echarts地图显示
16 1
|
2月前
|
定位技术
使用Echarts实现地图展示
使用Echarts实现地图展示
|
2月前
|
JSON JavaScript 定位技术
Vue中使用echarts@4.x中国地图及AMap相关API的使用
Vue中使用echarts@4.x中国地图及AMap相关API的使用
234 0
Vue中使用echarts@4.x中国地图及AMap相关API的使用
|
2月前
|
JSON 程序员 定位技术
使用echarts+echarts-gl绘制3d地图,实现地图轮播效果
记录一下大屏开发中使用到的echarts-gl 大屏的页面根据需求前前后后改了几个版本了,地图的样式也改了又改 这里记录一下,因为echarts属性用到的比较多也比较杂,防止以后需要用到忘记了
|
2月前
|
定位技术
echarts显示地图
echarts显示地图