Highcharts 时钟(详细教程)

什么是 Highcharts 时钟?

在前端开发的世界里,图表库就像是程序员的“画笔”。而 Highcharts,正是其中最广为人知的那支。它功能强大,支持多种图表类型,从柱状图到热力图,应有尽有。但今天我们要聊的不是常规图表,而是它的“另类玩法”——用 Highcharts 实现一个动态的时钟。

Highcharts 时钟,不是那种挂在墙上的物理时钟,而是一个在网页上实时走动、能显示当前时间的可视化组件。它借助 Highcharts 的极强自定义能力,将时间的流逝以“指针旋转”的方式呈现出来。想象一下,秒针像一条优雅的舞者,在圆盘上划出优美的弧线,每过一秒,它就向前移动一点。这种视觉表达,比单纯的数字时间更有温度。

为什么用 Highcharts 做时钟?因为它的极简配置、强大的动画支持和灵活的坐标系统,让绘制圆形、旋转元素变得异常轻松。你不需要写复杂的 Canvas 代码,也不必处理角度转换的数学难题。Highcharts 已经帮你封装好了这些底层逻辑。

更重要的是,这种实践对初学者非常友好。它融合了时间计算、DOM 操作、定时器、坐标系理解等多个知识点,是一次全面的实战演练。


准备工作:引入 Highcharts

在开始之前,你需要把 Highcharts 引入你的项目。这一步就像搭积木前先准备好积木块。

打开你的 HTML 文件,加入以下代码:

<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8" />
  <title>Highcharts 时钟</title>
  <!-- 引入 Highcharts CDN -->
  <script src="https://cdn.jsdelivr.net/npm/highcharts@11.0.1/dist/highcharts.js"></script>
  <style>
    #clock-container {
      width: 400px;
      height: 400px;
      margin: 50px auto;
      border: 1px solid #ddd;
      border-radius: 50%;
      box-shadow: 0 0 15px rgba(0, 0, 0, 0.1);
    }
  </style>
</head>
<body>
  <!-- 时钟容器 -->
  <div id="clock-container"></div>

  <script>
    // 后续 JavaScript 代码将放在这里
  </script>
</body>
</html>

这段代码做了几件事:

  • 使用 cdn.jsdelivr.net 引入 Highcharts 的最新版本(11.0.1),确保你使用的是最新稳定版。
  • 创建一个 div 容器,ID 为 clock-container,它将作为时钟的“画布”。
  • 添加了简单的 CSS,让容器变成一个圆形,带边框和阴影,视觉上更像一个真实的钟面。

注意:所有代码必须放在 <script> 标签中,否则 Highcharts 无法渲染。


构建时钟的骨架:基础图表配置

现在我们来创建一个基本的 Highcharts 图表,它将作为时钟的“骨架”。

// 初始化 Highcharts 图表
const chart = Highcharts.chart('clock-container', {
  chart: {
    type: 'gauge',           // 使用仪表盘类型,适合圆形显示
    backgroundColor: 'transparent', // 背景透明,突出钟面
    plotBorderWidth: 0,      // 去掉默认边框
    margin: [0, 0, 0, 0]     // 缩减边距,让图表紧贴容器
  },
  title: {
    text: null               // 不显示标题
  },
  pane: {
    startAngle: -90,         // 钟面起始角度为 -90 度(即顶部为 12 点方向)
    endAngle: 270,           // 结束角度为 270 度(完整一圈)
    background: null         // 不显示背景色,保持干净
  },
  tooltip: {
    enabled: false           // 关闭提示框,避免干扰
  },
  yAxis: {
    min: 0,
    max: 60,
    tickPositions: [],       // 不显示刻度线
    labels: {
      enabled: false         // 不显示数字标签
    },
    plotBands: []            // 不添加区间背景
  },
  series: []
});

解释一下关键配置:

  • type: 'gauge':这是 Highcharts 中专为仪表盘设计的类型。它默认支持指针、刻度和环形布局,非常适合做时钟。
  • startAngle: -90endAngle: 270:这定义了钟面的起始和结束角度。-90 度正好指向顶部(12 点方向),而 270 度绕一圈回到原点,构成完整的 360 度。
  • plotBandstickPositions 都设为空数组,因为我们不需要常规的刻度线,而是手动画出时钟刻度。

现在,你已经搭好了时钟的“骨架”。下一步,我们要给它“装上指针”。


添加指针:秒针、分针、时针

时钟的灵魂在于指针。Highcharts 的 series 可以添加多个指针,每个指针代表一个时间单位。

// 添加三个指针:秒针、分针、时针
chart.addSeries({
  name: '秒针',
  data: [0],
  color: '#FF0000',         // 红色,醒目
  tooltip: {
    valueSuffix: ' 秒'
  },
  // 指针样式
  dial: {
    radius: '80%',         // 指针长度占容器半径的 80%
    backgroundColor: '#FF0000',
    borderWidth: 2,
    borderColor: '#FF0000'
  },
  // 指针末端样式
  pivot: {
    radius: 5,
    backgroundColor: '#FF0000'
  }
});

chart.addSeries({
  name: '分针',
  data: [0],
  color: '#0000FF',
  tooltip: {
    valueSuffix: ' 分钟'
  },
  dial: {
    radius: '70%',
    backgroundColor: '#0000FF',
    borderWidth: 3,
    borderColor: '#0000FF'
  },
  pivot: {
    radius: 6,
    backgroundColor: '#0000FF'
  }
});

chart.addSeries({
  name: '时针',
  data: [0],
  color: '#000000',
  tooltip: {
    valueSuffix: ' 小时'
  },
  dial: {
    radius: '50%',
    backgroundColor: '#000000',
    borderWidth: 4,
    borderColor: '#000000'
  },
  pivot: {
    radius: 8,
    backgroundColor: '#000000'
  }
});

这里的关键是 dialpivot 配置:

  • radius: '80%':指针长度占整个圆盘半径的 80%,也就是从中心到边缘的 80% 位置。
  • borderWidthborderColor:控制指针的粗细和颜色。
  • pivot:指针的“头部”或“旋转中心”,它是一个小圆点,让指针看起来更真实。

小提示:你可以通过调整 radius 值来改变指针长度,比如把秒针设为 90%,让它更长,更显眼。


实现动态更新:使用 setInterval

时钟的核心是“动起来”。我们需要每秒更新一次时间,并重新渲染指针位置。

// 定时器:每秒更新一次
setInterval(() => {
  const now = new Date();        // 获取当前时间
  const seconds = now.getSeconds();     // 获取秒
  const minutes = now.getMinutes();     // 获取分钟
  const hours = now.getHours() % 12;    // 获取小时(12小时制)

  // 更新秒针:360度 / 60秒 = 每秒 6 度
  const secondAngle = seconds * 6;        // 1 秒 = 6 度
  chart.series[0].points[0].update(secondAngle); // 更新秒针角度

  // 更新分针:360度 / 60分钟 = 每分钟 6 度,加上秒的影响
  const minuteAngle = minutes * 6 + seconds * 0.1; // 每秒移动 0.1 度
  chart.series[1].points[0].update(minuteAngle);

  // 更新时针:360度 / 12小时 = 每小时 30 度,加上分钟的影响
  const hourAngle = hours * 30 + minutes * 0.5; // 每分钟移动 0.5 度
  chart.series[2].points[0].update(hourAngle);

}, 1000); // 每 1000 毫秒(1秒)执行一次

这段代码的核心逻辑是:

  • new Date() 获取当前时间对象。
  • 秒针每秒移动 6 度(360 / 60),所以 seconds * 6
  • 分针每分钟移动 6 度,但每秒还会额外移动 0.1 度(因为 6 度 / 60 秒),所以 minutes * 6 + seconds * 0.1
  • 时针每小时移动 30 度(360 / 12),每分钟移动 0.5 度(30 / 60),所以 hours * 30 + minutes * 0.5

为什么用 update()?因为 Highcharts 的 series[0].points[0] 是指针的“数据点”,调用 update(angle) 就能改变其旋转角度。


美化时钟:添加刻度和数字

为了让时钟更像一个真正的钟,我们加上 12 个数字和 60 个刻度。

// 添加刻度线和数字
for (let i = 1; i <= 12; i++) {
  // 计算角度:12 个数字,每30度一个
  const angle = (i - 3) * 30; // 调整起始点为 12 点方向

  // 添加刻度线(长)
  chart.addSeries({
    type: 'line',
    data: [
      [0, 0],
      [0.7, 0]
    ],
    color: '#000',
    lineWidth: 2,
    dashStyle: 'solid',
    // 设置旋转
    pointPlacement: 'on',
    rotation: angle,
    // 位置偏移
    marker: {
      enabled: false
    }
  });

  // 添加数字(可选,用文本)
  chart.addSeries({
    type: 'label',
    data: [
      {
        x: 0.85 * 100, // 位置在 85% 半径处
        y: 0,
        text: i.toString(),
        style: {
          fontSize: '16px',
          fontWeight: 'bold',
          color: '#000'
        }
      }
    ],
    rotation: angle,
    align: 'center',
    verticalAlign: 'middle',
    zIndex: 10
  });
}

这个循环为 12 个数字分别添加了:

  • 一条长线(刻度线),代表小时位置。
  • 一个文字标签(数字 1 到 12),通过 rotation 实现旋转对齐。

你也可以用更精细的方式添加 5 秒刻度线,但为初学者,当前版本已足够清晰。


总结:Highcharts 时钟的完整价值

Highcharts 时钟不仅仅是一个“炫技”项目。它融合了时间计算、DOM 操作、定时器、坐标系理解、动画控制等多个前端核心技能。通过它,你可以:

  • 理解 Highcharts 的 gauge 类型如何工作;
  • 掌握 setInterval 与动态更新的结合;
  • 学会如何通过角度计算控制指针旋转;
  • 提升对“可视化时间”的感知能力。

更重要的是,它让你明白:技术不是冷冰冰的代码,而是可以表达时间、美感与温度的工具

当你在浏览器中看到秒针优雅地划过,分针缓缓推进,时针坚定前行,那一刻,你不仅是在写代码,更是在创造一种“时间的仪式感”。

Highcharts 时钟,不仅是一个功能组件,更是一种前端美学的体现。无论你是初学者还是中级开发者,都值得花半小时亲手实现一次。动手吧,让时间在你的代码中跳动。