一图双粒度|用Highcharts 开发共用时间 X 轴的不同数据间隔图表+JS代码

本案例是 Highcharts时间轴 X 轴(datetime)+ 双系列不同数据间隔的经典实战场景。

核心实现:同一个时间 X 轴,同时渲染 30 年聚合柱状图 + 年度细粒度折线图,适用于「粗粒度统计 + 细粒度趋势」对比展示,广泛用于气象、金融、历史数据统计等场景。

我从 NASA GISS 获取了 1880-2021 年全球地表温度异常数据(相对于 1951-1980 年均值),并整合到Highcharts 代码中。

从柱状图可以清晰看到全球变暖的阶梯式上升趋势——从 19 世纪末的负异常,到 20 世纪中叶接近零,再到 21 世纪初显著的正异常,温度上升了近 1°C

折线图展示了每年的温度波动,可以清晰看到 1998 年、2016 年、2020 年等强厄尔尼诺年份的显著升温峰值。

在本可视化案例中,Highcharts 展现了强大的时间序列与多粒度数据渲染能力。它支持在同一个时间轴上同时呈现30 年区间柱状图年度精细折线图,解决了长期趋势与短期变化无法同图展示的行业痛点。

通过 pointRange 可自由定义时间跨度,无需手动处理坐标偏移;支持从 DOM 读取数据,便于前后端分离项目集成;内置时间格式化、多系列共享提示、自适应布局,让图表呈现专业、美观、易读。

Highcharts 无需插件即可实现科研级可视化效果,代码简洁、扩展性强,是气象监测、环境分析、历史趋势研究、学术报告等场景的首选前端可视化方案。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Global Temperature Changes 1880-2021</title>
    <script src="https://code.highcharts.com/highcharts.js"></script>
    <script src="https://code.highcharts.com/modules/accessibility.js"></script>
    <style>
        body { font-family: Arial, sans-serif; margin: 40px; background: #f5f5f5; }
        #container { width: 100%; max-width: 1200px; height: 600px; margin: 0 auto; }
        h1 { text-align: center; color: #333; }
        .data-hidden { display: none; }
    </style>
<base target="_blank">
</head>
<body>
    <h1>Global Temperature Changes from 1880 to 2021</h1>
    <div id="container"></div>

    <script id="lineData" type="application/json">
    [
        [Date.UTC(1880, 0, 1), -0.18], [Date.UTC(1881, 0, 1), -0.09], [Date.UTC(1882, 0, 1), -0.11],
        [Date.UTC(1883, 0, 1), -0.17], [Date.UTC(1884, 0, 1), -0.28], [Date.UTC(1885, 0, 1), -0.34],
        [Date.UTC(1886, 0, 1), -0.32], [Date.UTC(1887, 0, 1), -0.37], [Date.UTC(1888, 0, 1), -0.18],
        [Date.UTC(1889, 0, 1), -0.11], [Date.UTC(1890, 0, 1), -0.36], [Date.UTC(1891, 0, 1), -0.22],
        [Date.UTC(1892, 0, 1), -0.27], [Date.UTC(1893, 0, 1), -0.31], [Date.UTC(1894, 0, 1), -0.31],
        [Date.UTC(1895, 0, 1), -0.23], [Date.UTC(1896, 0, 1), -0.12], [Date.UTC(1897, 0, 1), -0.11],
        [Date.UTC(1898, 0, 1), -0.28], [Date.UTC(1899, 0, 1), -0.18], [Date.UTC(1900, 0, 1), -0.09],
        [Date.UTC(1901, 0, 1), -0.16], [Date.UTC(1902, 0, 1), -0.28], [Date.UTC(1903, 0, 1), -0.37],
        [Date.UTC(1904, 0, 1), -0.47], [Date.UTC(1905, 0, 1), -0.26], [Date.UTC(1906, 0, 1), -0.22],
        [Date.UTC(1907, 0, 1), -0.39], [Date.UTC(1908, 0, 1), -0.43], [Date.UTC(1909, 0, 1), -0.49],
        [Date.UTC(1910, 0, 1), -0.44], [Date.UTC(1911, 0, 1), -0.45], [Date.UTC(1912, 0, 1), -0.37],
        [Date.UTC(1913, 0, 1), -0.35], [Date.UTC(1914, 0, 1), -0.15], [Date.UTC(1915, 0, 1), -0.14],
        [Date.UTC(1916, 0, 1), -0.36], [Date.UTC(1917, 0, 1), -0.46], [Date.UTC(1918, 0, 1), -0.30],
        [Date.UTC(1919, 0, 1), -0.28], [Date.UTC(1920, 0, 1), -0.28], [Date.UTC(1921, 0, 1), -0.19],
        [Date.UTC(1922, 0, 1), -0.28], [Date.UTC(1923, 0, 1), -0.27], [Date.UTC(1924, 0, 1), -0.27],
        [Date.UTC(1925, 0, 1), -0.22], [Date.UTC(1926, 0, 1), -0.11], [Date.UTC(1927, 0, 1), -0.22],
        [Date.UTC(1928, 0, 1), -0.20], [Date.UTC(1929, 0, 1), -0.36], [Date.UTC(1930, 0, 1), -0.16],
        [Date.UTC(1931, 0, 1), -0.09], [Date.UTC(1932, 0, 1), -0.16], [Date.UTC(1933, 0, 1), -0.29],
        [Date.UTC(1934, 0, 1), -0.13], [Date.UTC(1935, 0, 1), -0.20], [Date.UTC(1936, 0, 1), -0.15],
        [Date.UTC(1937, 0, 1), -0.03], [Date.UTC(1938, 0, 1), 0.00], [Date.UTC(1939, 0, 1), -0.02],
        [Date.UTC(1940, 0, 1), 0.12], [Date.UTC(1941, 0, 1), 0.18], [Date.UTC(1942, 0, 1), 0.06],
        [Date.UTC(1943, 0, 1), 0.09], [Date.UTC(1944, 0, 1), 0.20], [Date.UTC(1945, 0, 1), 0.09],
        [Date.UTC(1946, 0, 1), -0.07], [Date.UTC(1947, 0, 1), -0.03], [Date.UTC(1948, 0, 1), -0.11],
        [Date.UTC(1949, 0, 1), -0.11], [Date.UTC(1950, 0, 1), -0.18], [Date.UTC(1951, 0, 1), -0.07],
        [Date.UTC(1952, 0, 1), 0.01], [Date.UTC(1953, 0, 1), 0.08], [Date.UTC(1954, 0, 1), -0.13],
        [Date.UTC(1955, 0, 1), -0.14], [Date.UTC(1956, 0, 1), -0.19], [Date.UTC(1957, 0, 1), 0.05],
        [Date.UTC(1958, 0, 1), 0.06], [Date.UTC(1959, 0, 1), 0.03], [Date.UTC(1960, 0, 1), -0.02],
        [Date.UTC(1961, 0, 1), 0.06], [Date.UTC(1962, 0, 1), 0.03], [Date.UTC(1963, 0, 1), 0.05],
        [Date.UTC(1964, 0, 1), -0.20], [Date.UTC(1965, 0, 1), -0.11], [Date.UTC(1966, 0, 1), -0.06],
        [Date.UTC(1967, 0, 1), -0.02], [Date.UTC(1968, 0, 1), -0.08], [Date.UTC(1969, 0, 1), 0.05],
        [Date.UTC(1970, 0, 1), 0.03], [Date.UTC(1971, 0, 1), -0.08], [Date.UTC(1972, 0, 1), 0.01],
        [Date.UTC(1973, 0, 1), 0.16], [Date.UTC(1974, 0, 1), -0.07], [Date.UTC(1975, 0, 1), -0.01],
        [Date.UTC(1976, 0, 1), -0.10], [Date.UTC(1977, 0, 1), 0.18], [Date.UTC(1978, 0, 1), 0.07],
        [Date.UTC(1979, 0, 1), 0.16], [Date.UTC(1980, 0, 1), 0.26], [Date.UTC(1981, 0, 1), 0.32],
        [Date.UTC(1982, 0, 1), 0.14], [Date.UTC(1983, 0, 1), 0.31], [Date.UTC(1984, 0, 1), 0.16],
        [Date.UTC(1985, 0, 1), 0.12], [Date.UTC(1986, 0, 1), 0.18], [Date.UTC(1987, 0, 1), 0.32],
        [Date.UTC(1988, 0, 1), 0.39], [Date.UTC(1989, 0, 1), 0.27], [Date.UTC(1990, 0, 1), 0.45],
        [Date.UTC(1991, 0, 1), 0.40], [Date.UTC(1992, 0, 1), 0.22], [Date.UTC(1993, 0, 1), 0.23],
        [Date.UTC(1994, 0, 1), 0.31], [Date.UTC(1995, 0, 1), 0.44], [Date.UTC(1996, 0, 1), 0.33],
        [Date.UTC(1997, 0, 1), 0.46], [Date.UTC(1998, 0, 1), 0.61], [Date.UTC(1999, 0, 1), 0.38],
        [Date.UTC(2000, 0, 1), 0.39], [Date.UTC(2001, 0, 1), 0.53], [Date.UTC(2002, 0, 1), 0.63],
        [Date.UTC(2003, 0, 1), 0.61], [Date.UTC(2004, 0, 1), 0.53], [Date.UTC(2005, 0, 1), 0.68],
        [Date.UTC(2006, 0, 1), 0.64], [Date.UTC(2007, 0, 1), 0.66], [Date.UTC(2008, 0, 1), 0.54],
        [Date.UTC(2009, 0, 1), 0.66], [Date.UTC(2010, 0, 1), 0.72], [Date.UTC(2011, 0, 1), 0.61],
        [Date.UTC(2012, 0, 1), 0.64], [Date.UTC(2013, 0, 1), 0.68], [Date.UTC(2014, 0, 1), 0.75],
        [Date.UTC(2015, 0, 1), 0.90], [Date.UTC(2016, 0, 1), 1.01], [Date.UTC(2017, 0, 1), 0.92],
        [Date.UTC(2018, 0, 1), 0.85], [Date.UTC(2019, 0, 1), 0.98], [Date.UTC(2020, 0, 1), 1.01],
        [Date.UTC(2021, 0, 1), 0.85]
    ]
    </script>

    <script id="columnData" type="application/json">
    [
        [Date.UTC(1909, 0, 1), -0.257],
        [Date.UTC(1939, 0, 1), -0.231],
        [Date.UTC(1969, 0, 1), -0.012],
        [Date.UTC(1999, 0, 1), 0.222],
        [Date.UTC(2021, 0, 1), 0.718]
    ]
    </script>

    <script>
    Highcharts.chart('container', {
        title: {
            text: 'Global temperature changes from 1880 to 2021'
        },
        accessibility: {
            description: `
                A chart of global temperature change from 1880 to 2021.
                It employs two series, one column and one line,
                to convey the same data at different resolutions.
                There is only one column per thirty years,
                but the line series have a datapoint per year.
            `
        },
        series: [{
            type: 'column',
            name: 'Mean per thirty years',
            data: JSON.parse(document.getElementById('columnData').textContent),
            pointRange: 30 * 365 * 24 * 36e5,
            groupPadding: 0,
            pointPadding: 0,
            pointPlacement: -0.5,
            tooltip: {
                headerFormat: '<span style="font-size: 0.8em;">{subtract (point.x:%Y) 30} - {point.x:%Y}</span><br>'
            }
        }, {
            name: 'Annual mean',
            data: JSON.parse(document.getElementById('lineData').textContent),
            accessibility: {
                description: `
                    A data series illustrating the same data as the first,
                    but at different time intervals
                `
            }
        }],
        tooltip: {
            valueSuffix: '°C',
            valueDecimals: 2
        },
        yAxis: {
            accessibility: {
                description: 'temperature'
            },
            minPadding: 0,
            maxPadding: 0,
            labels: {
                format: '{value:.1f}°C'
            },
            name: 'Temperature change',
            title: {
                text: 'Temp anomaly (compared to 1951-1980 avg.)'
            }
        },
        xAxis: {
            endOnTick: true,
            type: 'datetime'
        }
    });
    </script>
</body>
</html>

本案例实现Highcharts 最常用的高级场景

  • 共用时间类型 X 轴(datetime)
  • 两个数据系列时间间隔完全不同: ✅ 柱状图:30 年一个数据点(粗粒度统计); ✅ 折线图:1 年一个数据点(细粒度趋势);
  • 自动适配时间轴,无需手动校准位置;
  • 自定义悬浮提示、单位、样式。

关键配置项解析

配置项 作用
xAxis.type = 'datetime' 声明 X 轴为时间轴,支持时间戳、自动格式化时间
series[0].pointRange 定义柱状图每个柱子的时间跨度(30 年)
series[0].tooltip 自定义提示框,自动计算并展示「起始年 - 结束年」
data: JSON.parse(...) 从页面 DOM 读取 JSON 数据,解耦数据与配置
yAxis.labels.format Y 轴数值格式化,保留 1 位小数 + 气温单位

附:Highcharts 图表类型解析(案例涉及)

1. 柱状图(column)

  • 英文标识column
  • 特点:适合分类 / 时间聚合数据、粗粒度统计、视觉对比清晰。

2. 折线图(line)

  • 英文标识line(默认类型,无需手动声明)
  • 特点:连续数据、趋势展示、变化感知直观。

3. 时间轴(datetime X 轴)

  • Highcharts专用时间类型轴,自动识别时间戳;
  • 支持不同间隔数据完美共存(1 年 / 30 年 / 10 年均可);
  • 自动格式化时间(年 / 月 / 日),是气象、金融、历史数据标配。

总结:Highcharts 图表开发优势

1. 完美支持「同 X 轴不同数据间隔」

无需复杂计算,时间轴自动对齐不同粒度数据,是行业内最优解决方案

2. 纯 JS 实现,无第三方依赖

直接引入 CDN 即可运行,兼容所有浏览器,无需插件。

3. 中文友好,配置语义化极强

所有配置项通俗易懂,支持中文标题、提示、单位,快速落地中文项目。

4. 交互体验原生优秀

支持鼠标悬浮查看详情、时间轴缩放、图例切换、数据导出等功能。

5. 数据与配置解耦

支持 DOM 读取、接口请求、变量赋值等多种数据接入方式,适合企业级开发。

6. 响应式适配

自动适配 PC、平板、手机,无需额外编写适配代码。

最后,本案例「同 X 轴不同数据间隔」模式,是 Highcharts 企业级开发高频用法,也是 Highcharts时间轴可视化的标杆用法,解决了行业内高频需求:同一时间维度下,同时展示细粒度趋势与粗粒度统计

  • 开发成本极低:复制代码即可运行,修改数据即可适配业务;
  • 兼容性极强:支持所有浏览器、所有设备;
  • 扩展性极高:可接入接口动态数据、添加 3D 效果、多 Y 轴、导出功能。
posted @ 2026-06-06 09:35  Highcharts  阅读(4)  评论(0)    收藏  举报