欢迎光临
我们一直在努力

用Highcharts 创建可拖拽三维散点立方体3D图表

该案例基于Highcharts  scatter3d 三维散点图实现空间立方体散点可视化,核心特色:

  • 三维 X/Y/Z 三轴空间,所有散点分布在 0~10 立方体空间内;
  • 散点使用径向渐变实现立体 3D 圆球质感;
  • 支持鼠标 / 触屏拖拽画布,自由旋转三维视角;
  • 带 3D 立体边框框架,还原空间盒子视觉。
  • 依赖前置

    scatter3d 三维图表依赖扩展包:highcharts-3d.js,必须引入才能渲染三维坐标轴、拖拽旋转逻辑。

    代码分模块深度解析

    模块 1:全局渐变统一配置 Highcharts.setOptions

    Highcharts.setOptions({
    colors: Highcharts.getOptions().colors.map(function (color) {
    return {
    radialGradient: { cx: 0.4, cy: 0.3, r: 0.5 },
    stops: [
    [0, color],
    [1, Highcharts.color(color).brighten(-0.2).get('rgb')]
    ]
    };
    })
    });

  • 全局覆盖所有系列默认颜色,将纯色替换为径向渐变;
  • 渐变圆心偏移 cx/cy,模拟球体高光;
  • 渐变终点将基础颜色压暗 20%,形成球体明暗对比,平面圆点呈现立体圆球效果;
  • 配合 colorByPoint: true,每个散点自动分配不同渐变色彩。
  • 模块 2:Chart 画布与 3D 核心配置

    chart: {
    renderTo: 'container',
    margin: 100,
    type: 'scatter3d',
    animation: false,
    options3d: {
    enabled: true,
    alpha: 10, // 垂直俯仰角度
    beta: 30, // 水平旋转角度
    depth: 250, // 三维纵深深度
    viewDistance: 5,
    fitToPlot: false,
    frame: { // 立方体三维边框
    bottom: { size: 1, color: 'rgba(0,0,0,0.02)' },
    back: { size: 1, color: 'rgba(0,0,0,0.04)' },
    side: { size: 1, color: 'rgba(0,0,0,0.06)' }
    }
    }
    }

    关键 3D 参数说明:

    • alpha:上下俯仰角度,数值越大俯视越明显;
    • beta:左右水平旋转角度;
    • depth:控制 3D 透视拉伸程度;
    • frame:绘制立方体底面、背面、侧面边框,打造封闭空间盒子;
    • animation: false:关闭渲染动画,拖拽旋转更流畅。

    模块 3:散点样式 plotOptions

    plotOptions: {
    scatter: {
    width: 10,
    height: 10,
    depth: 10
    }
    }

    三维散点长宽高统一为 10 单位,形成标准正立方体小球,长宽深一致保证球体不变形。

    模块 4:三轴坐标轴配置

    xAxis/yAxis/zAxis: { min:0, max:10 }

    三轴统一值域 0~10,构成规整立方体空间;隐藏 Z 轴首刻度、Y 轴标题,简化画布视觉。

    模块 5:数据系列 Series

    series: [{
    name: 'Data',
    colorByPoint: true, // 每个点自动分配不同渐变颜色
    data: [ [x,y,z], [x,y,z], … ]
    }]

  • 数据格式:三维数组 [横坐标X,纵坐标Y,纵深Z];
  • colorByPoint: true:单个散点独立配色,区分空间点位;
  • accessibility.exposeAsGroupOnly:无障碍模式将所有散点识别为一组,减少读屏冗余播报。
  • 模块 6:自定义拖拽旋转事件(核心交互扩展)

    原生 3D 图表无内置拖拽旋转逻辑,代码手动封装鼠标 / 触屏拖拽:

  • 监听 mousedown/touchstart 记录鼠标初始坐标、初始俯仰 / 旋转角度;
  • 拖动 mousemove/touchmove 时,根据鼠标偏移量实时修改 alpha/beta 视角参数;
  • sensitivity=5 控制拖拽灵敏度,数值越小旋转越灵敏;
  • 鼠标松开 / 触屏结束 mouseup/touchend 解绑事件,停止旋转;
  • 同时兼容 PC 鼠标、手机触屏双端操作。
  • 可运行代码

    html 预览

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
    <meta charset="UTF-8">
    <title>3D可拖拽立方体散点图</title>
    <script src="https://code.highcharts.com/highcharts.js"></script>
    <script src="https://code.highcharts.com/highcharts-3d.js"></script>
    <style>
    #container {
    width: 100%;
    height: 650px;
    }
    </style>
    </head>
    <body>
    <div id="container"></div>
    <script>
    // 全局配置:散点径向渐变,实现3D圆球质感
    Highcharts.setOptions({
    colors: Highcharts.getOptions().colors.map(function (color) {
    return {
    radialGradient: {
    cx: 0.4,
    cy: 0.3,
    r: 0.5
    },
    stops: [
    [0, color],
    [1, Highcharts.color(color).brighten(-0.2).get('rgb')]
    ]
    };
    })
    });

    // 初始化3D图表
    const chart = new Highcharts.Chart({
    chart: {
    renderTo: 'container',
    margin: 100,
    type: 'scatter3d',
    animation: false,
    options3d: {
    enabled: true,
    alpha: 10,
    beta: 30,
    depth: 250,
    viewDistance: 5,
    fitToPlot: false,
    frame: {
    bottom: { size: 1, color: 'rgba(0,0,0,0.02)' },
    back: { size: 1, color: 'rgba(0,0,0,0.04)' },
    side: { size: 1, color: 'rgba(0,0,0,0.06)' }
    }
    }
    },
    title: {
    text: '可拖拽三维立方体散点图'
    },
    subtitle: {
    text: '按住鼠标拖动画布,可360°旋转三维空间'
    },
    plotOptions: {
    scatter: {
    width: 10,
    height: 10,
    depth: 10
    }
    },
    yAxis: {
    min: 0,
    max: 10,
    title: { text: 'Y轴' }
    },
    xAxis: {
    min: 0,
    max: 10,
    title: { text: 'X轴' },
    gridLineWidth: 1
    },
    zAxis: {
    min: 0,
    max: 10,
    title: { text: 'Z轴' },
    showFirstLabel: false
    },
    legend: {
    enabled: false
    },
    series: [{
    name: '空间采样点',
    colorByPoint: true,
    accessibility: {
    exposeAsGroupOnly: true
    },
    data: [
    [1, 6, 5], [8, 7, 9], [1, 3, 4], [4, 6, 8], [5, 7, 7], [6, 9, 6],
    [7, 0, 5], [2, 3, 3], [3, 9, 8], [3, 6, 5], [4, 9, 4], [2, 3, 3],
    [6, 9, 9], [0, 7, 0], [7, 7, 9], [7, 2, 9], [0, 6, 2], [4, 6, 7],
    [3, 7, 7], [0, 1, 7], [2, 8, 6], [2, 3, 7], [6, 4, 8], [3, 5, 9],
    [7, 9, 5], [3, 1, 7], [4, 4, 2], [3, 6, 2], [3, 1, 6], [6, 8, 5],
    [6, 6, 7], [4, 1, 1], [7, 2, 7], [7, 7, 0], [8, 8, 9], [9, 4, 1],
    [8, 3, 4], [9, 8, 9], [3, 5, 3], [0, 2, 4], [6, 0, 2], [2, 1, 3],
    [5, 8, 9], [2, 1, 1], [9, 7, 6], [3, 0, 2], [9, 9, 0], [3, 4, 8],
    [2, 6, 1], [8, 9, 2], [7, 6, 5], [6, 3, 1], [9, 3, 1], [8, 9, 3],
    [9, 1, 0], [3, 8, 7], [8, 0, 0], [4, 9, 7], [8, 6, 2], [4, 3, 0],
    [2, 3, 5], [9, 1, 4], [1, 1, 4], [6, 0, 2], [6, 1, 6], [3, 8, 8],
    [8, 8, 7], [5, 5, 0], [3, 9, 6], [5, 4, 3], [6, 8, 3], [0, 1, 5],
    [6, 7, 3], [8, 3, 2], [3, 8, 3], [2, 1, 6], [4, 6, 7], [8, 9, 9],
    [5, 4, 2], [6, 1, 3], [6, 9, 5], [4, 8, 2], [9, 7, 4], [5, 4, 2],
    [9, 6, 1], [2, 7, 3], [4, 5, 4], [6, 8, 1], [3, 4, 0], [2, 2, 6],
    [5, 1, 2], [9, 9, 7], [6, 9, 9], [8, 4, 3], [4, 1, 7], [6, 2, 5],
    [0, 4, 9], [3, 5, 9], [6, 9, 1], [1, 9, 2]
    ]
    }]
    });

    // 自定义鼠标、触屏拖拽旋转逻辑
    (function (H) {
    function dragStart(eStart) {
    eStart = chart.pointer.normalize(eStart);

    const posX = eStart.chartX,
    posY = eStart.chartY,
    alpha = chart.options.chart.options3d.alpha,
    beta = chart.options.chart.options3d.beta,
    sensitivity = 5,
    handlers = [];

    function drag(e) {
    e = chart.pointer.normalize(e);
    chart.update({
    chart: {
    options3d: {
    alpha: alpha + (e.chartY – posY) / sensitivity,
    beta: beta + (posX – e.chartX) / sensitivity
    }
    }
    }, undefined, undefined, false);
    }

    function unbindAll() {
    handlers.forEach(function (unbind) {
    if (unbind) unbind();
    });
    handlers.length = 0;
    }

    handlers.push(H.addEvent(document, 'mousemove', drag));
    handlers.push(H.addEvent(document, 'touchmove', drag));
    handlers.push(H.addEvent(document, 'mouseup', unbindAll));
    handlers.push(H.addEvent(document, 'touchend', unbindAll));
    }
    H.addEvent(chart.container, 'mousedown', dragStart);
    H.addEvent(chart.container, 'touchstart', dragStart);
    }(Highcharts));
    </script>
    </body>
    </html>

    业务数据解读

    所有散点均匀分布在 X:0~10、Y:0~10、Z:0~10 的标准立方体三维空间,无集中聚集区域,属于均匀随机三维采样点; 拖拽旋转可从正面、侧面、俯视、仰视多角度观察点位空间分布,解决二维图表无法表达三维空间关系的痛点。

    Highcharts 实现 3D 散点图核心优势

  • 原生三维坐标轴体系 内置 scatter3d 三维散点、3D 框架渲染,自带透视、俯仰 / 旋转参数,无需引入 WebGL 复杂三维库;
  • 灵活图形美化 全局批量配置径向渐变,一键实现立体圆球散点,不用逐个修改点位样式;
  • 交互高度可扩展 原生无拖拽旋转,但提供完整事件监听 API,可自主扩展鼠标、触屏旋转、缩放、框选等交互;
  • 多端兼容 拖拽逻辑同时适配 PC 鼠标、移动端触屏,一套代码兼顾大屏与手机;
  • 轻量化集成 依托 Highcharts 基础生态,可无缝嵌入 Vue/React 后台、数字孪生、数据分析大屏;
  • 完整无障碍支持 内置 accessibility 配置,支持屏幕阅读器读取三维空间数据。
  • 附、拓展应用场景

  • 工业仿真:零部件三维尺寸采样、设备传感器 XYZ 空间点位分布;
  • 数据分析:三维特征聚类、机器学习三维特征散点可视化;
  • 数字孪生:厂房设备三维坐标点位、仓储货物空间分布;
  • 科研测绘:地质三维采样、气象立体空间观测数据;
  • 教育可视化:数学三维坐标系教学演示。
  • 赞(0)
    未经允许不得转载:171主机测评 » 用Highcharts 创建可拖拽三维散点立方体3D图表
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址