You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Highcharts官方React封装的图表内渲染DatePicker组件

实现方案

核心逻辑是利用Highcharts的渲染接口在图表内部生成自定义DOM容器,再通过React Portal将DatePicker组件挂载到该容器中,完全支持函数式组件实现,修改后的代码如下:

首先需要从react中引入createPortalAPI,新增两个ref分别保存Highcharts实例、DatePicker挂载容器,完整可运行代码:

import { useState, useEffect, useRef } from 'react';
import { createPortal } from 'react-dom';
import Highcharts from 'highcharts/highstock';
import HighchartsReact from 'highcharts-react-official';
import DatePicker from 'react-datepicker';
import "react-datepicker/dist/react-datepicker.css";

function Graph(props) {
  const [startDate, setStartDate] = useState(new Date('1969-11-19 PST'));
  const [bx, setBx] = useState([]);
  const [by, setBy] = useState([]);
  const [bz, setBz] = useState([]);
  // 新增ref存储图表实例和日期选择器挂载容器
  const chartRef = useRef(null);
  const datePickerContainer = useRef(document.createElement('div'));

  async function getData(table, year, month, day) {
    // 原有数据请求逻辑保持不变
  }

  useEffect(() => {
    // 原有监听startDate拉取数据的逻辑保持不变
  }, [startDate])

  // 新增:更新日期选择器在图表内的位置
  const updateDatePickerPos = (chart) => {
    // 可自定义偏移数值调整位置,当前默认放在图表左上角
    datePickerContainer.current.style.position = 'absolute';
    datePickerContainer.current.style.left = `${chart.plotLeft + 10}px`;
    datePickerContainer.current.style.top = `${chart.plotTop + 10}px`;
    datePickerContainer.current.style.zIndex = '999'; // 确保不被图表SVG层遮挡
    chart.container.appendChild(datePickerContainer.current);
  }

  const options = {
    chart: {
      events: {
        load: function() {
          this.showLoading();
          setTimeout(this.hideLoading.bind(this), 2000);
          updateDatePickerPos(this);
        },
        redraw: function() {
          // 图表缩放、重绘时同步更新日期选择器位置
          updateDatePickerPos(this);
        }
      },
      zoomType: 'x'
    },
    lang: {
      noData: "Awaiting for data"
    },
    rangeSelector: {
      inputEnabled: false,
      buttons: [
        {
          type: 'all',
          text: '1d',
          title: 'View 1 Day'
        },
        {
          type: 'minute',
          count: 10,
          text: '10m',
          title: 'View 10 minutes'
        },
        {
          type: 'minute',
          count: 1,
          text: '1m',
          title: 'View 1 minutes'
        },
        {
          type: 'second',
          count: 30,
          text: '30s',
          title: 'View 30 seconds'
        },
      ]
    },
    title: {
      text: props.title
    },
    xAxis: {
      type: 'datetime'
    },
    time: {
      timezoneOffset: 8*60
    },
    series: [
      {
        marker: {
          enabled: true,
          radius: 2
        },
        color: 'red',
        name: 'Bx',
        pointStart: startDate.getTime(),
        pointInterval: 1000,
        data: bx
      },
      {
        marker: {
          enabled: true,
          radius: 2
        },
        color: 'blue',
        name: 'By',
        pointStart: startDate.getTime(),
        pointInterval: 1000,
        data: by
      },
      {
        marker: {
          enabled: true,
          radius: 2
        },
        color: 'green',
        name: 'Bz',
        pointStart: startDate.getTime(),
        pointInterval: 1000,
        data: bz
      }
    ]
  }

  const isValidDate = (date) => {
    date.getTime();
    const origDate = new Date('1969-11-19 PST');
    const finalDate = new Date('1970-04-03 PST');
    console.log("GET DATE", date.getTime())
    return origDate.getTime() <= date.getTime() && date.getTime() <= finalDate.getTime();
  }

  return (
    <React.Fragment>
      <HighchartsReact
        highcharts={Highcharts}
        constructorType={'stockChart'}
        options={options}
        ref={chartRef}
      />
      {/* 通过Portal将DatePicker挂载到图表内部容器 */}
      {createPortal(
        <DatePicker 
          selected={startDate}
          filterDate={isValidDate}
          onChange={(date) => setStartDate(date)}
        />,
        datePickerContainer.current
      )}
    </React.Fragment>
  );
}

注意事项

  • 可自行调整updateDatePickerPos方法中的left、top数值,修改DatePicker在图表内的摆放位置
  • 如果DatePicker的下拉弹窗被图表容器截断,可给图表外层容器添加overflow: visible样式
  • 可在组件卸载的useEffect回调中手动移除datePickerContainer节点,避免内存泄漏

内容的提问来源于stack exchange,提问作者matthewcy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 08:48:02