196Echarts - 自定义系列(Hexagonal Binning)

简介: 196Echarts - 自定义系列(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
    // });
});
目录
相关文章
|
7天前
|
计算机视觉
Echarts饼图,自定义饼图图例的排列方式, formatter使用语法
Echarts饼图,自定义饼图图例的排列方式, formatter使用语法
|
7天前
|
JSON JavaScript 定位技术
Echarts自定义地图显示区域,可以显示街道,小区,学校等区域
Echarts自定义地图显示区域,可以显示街道,小区,学校等区域
|
13天前
|
JavaScript 前端开发 数据可视化
ECharts 雷达图案例001-自定义节点动画
使用ECharts创建自定义雷达图,通过JavaScript动态更新高亮和交互反馈,增强用户体验。关键步骤包括:开启动画效果,数据更新时保持图表状态,鼠标悬浮时动态高亮指标,优化动画性能。案例展示了ECharts在数据可视化中的灵活性和表现力。[查看完整案例](https://download.csdn.net/download/No_Name_Cao_Ni_Mei/89454380)。
31 0
 ECharts 雷达图案例001-自定义节点动画
|
2月前
|
前端开发 JavaScript 定位技术
Docusaurus框架——react+antd+echarts自定义mdx生成图表代码解释文档
Docusaurus框架——react+antd+echarts自定义mdx生成图表代码解释文档
49 0
|
2月前
|
JavaScript
echarts_自定义graph关系图
echarts_自定义graph关系图
33 0
|
2月前
Echarts 热力图自定义开发
Echarts 热力图自定义开发
|
8月前
|
JSON 前端开发 数据格式
Echarts饼状图数据交互请求ajax自定义颜色
Echarts饼状图数据交互请求ajax自定义颜色
30 0
|
8月前
Echarts自定义tooltip显示内容(隐藏小圆点)
Echarts自定义tooltip显示内容(隐藏小圆点)
174 0
|
8月前
echarts自定义y轴刻度信息
echarts自定义y轴刻度信息
|
9月前
202Echarts - 自定义系列(Wind Barb)
202Echarts - 自定义系列(Wind Barb)
38 0

热门文章

最新文章