返回

结合Ant Design开发可伸缩SVG甘特图,打造交互式数据可视化

前端

如何结合Ant Design开发一个SVG伸缩甘特图

前言

在上一篇文章中,我们探讨了如何使用Ant Design实现甘特图布局。在本篇中,我们将深入探讨如何利用SVG(可缩放矢量图形)绘制可伸缩的甘特图,使其具有交互式和动态特性,从而提升用户体验。

SVG在甘特图中的优势

SVG具有以下优势,使其成为创建动态、交互式甘特图的理想选择:

  • 可伸缩性: SVG图形可以无损地缩放,在不同分辨率的设备上都能清晰显示。
  • 交互性: SVG元素可以绑定事件处理程序,实现交互式功能,如鼠标悬停、点击等。
  • 动态性: SVG图形可以通过JavaScript动态更新,实现实时数据可视化。

Ant Design SVG集成

Ant Design提供了一系列与SVG相关的组件和实用程序,可以无缝集成到你的项目中:

  • Icon: 用于显示SVG图标。
  • SVG: 用于渲染自定义SVG图形。
  • DomUtils: 用于操作SVG DOM。

创建SVG甘特图

要创建SVG甘特图,我们需要遵循以下步骤:

  1. 定义SVG画布: 使用<svg>元素定义画布,并设置适当的宽度和高度。
  2. 绘制甘特条: 使用<rect>元素绘制甘特条,并使用CSS样式设置颜色、大小和位置。
  3. 添加交互性: 使用addEventListener将事件处理程序绑定到甘特条,实现鼠标悬停、点击等交互功能。
  4. 实现动态更新: 使用JavaScript动态更新SVG图形,以响应数据变化或用户交互。

示例代码

以下示例演示了如何使用Ant Design和SVG创建可伸缩的甘特图:

import { useEffect, useRef } from "react";
import { SVG, Icon } from "antd";
import DomUtils from "antd/es/utils/Dom";

const Gantt = () => {
  const ref = useRef(null);

  useEffect(() => {
    const svg = ref.current;
    const data = [
      { start: "2023-01-01", end: "2023-02-01", label: "Task 1" },
      { start: "2023-02-01", end: "2023-03-01", label: "Task 2" },
    ];

    const defs = svg.querySelector("defs");
    const marker = DomUtils.createSVGElement("marker", { id: "arrow" });
    defs.appendChild(marker);

    for (const task of data) {
      const rect = DomUtils.createSVGElement("rect", {
        x: task.start,
        y: 0,
        width: task.end - task.start,
        height: 30,
        fill: "#389e0d",
      });

      const text = DomUtils.createSVGElement("text", {
        x: (task.start + task.end) / 2,
        y: 15,
        "text-anchor": "middle",
        "font-size": "12",
        fill: "white",
      });
      text.textContent = task.label;

      const arrow = DomUtils.createSVGElement("path", {
        d: "M0 0 L10 5 L0 10 Z",
        "marker-end": `url(#arrow)`,
        fill: "#389e0d",
      });
      DomUtils.insertAfter(arrow, text);

      const line = DomUtils.createSVGElement("line", {
        x1: task.end,
        y1: 0,
        x2: task.end,
        y2: 30,
        stroke: "#389e0d",
      });

      svg.appendChild(rect);
      svg.appendChild(text);
      svg.appendChild(arrow);
      svg.appendChild(line);
    }
  }, []);

  return <SVG ref={ref} viewBox="0 0 1000 300" />;
};

export default Gantt;

SEO优化