highcharts的甘特图设置滚动时表头固定,让其他内容跟随滚动

效果图:最左侧的分类列是跟随甘特图滚动的,因为这一列如果需要自定义,比如表格的话可能会存在行合并的情况,这个时候甘特图是没有办法做的,然后甘特图的表头又需要做滚动时固定,所以设置了甘特图滚动时,让指定元素跟随滚动
请添加图片描述

如果元素需要滚动,但是不显示滚动条的话可以设置

首先,确保目标元素具有固定的高度和宽度,并且超过该尺寸的内容会溢出。
将元素的 CSS 样式中的 overflow 属性设置为 hidden,以隐藏默认的滚动条。

<div style="overflow: hidden"></div>

highcharts监听滚动事件

const chart = Highcharts.chart('container', {
  chart: {
    ...
    },
    ...
  },
  ...
});
chart.scrollingContainer.addEventListener('scroll', (el) => {
    console.log(el);
});

引用到的包
highcharts-gantt.js下载地址

需要引入highcharts-gantt.js,moment.js

完整代码示例:

<template>
  <div style="width: 100%; height: 100%; display: flex">
    <div
      style="
        width: 100px;
        display: flex;
        flex-direction: column;
        height: 508px;
        margin: 10px 0 0 10px;
      "
    >
      <div
        style="
          height: 105px;
          border: 1px solid #ccc;
          display: flex;
          align-items: center;
          justify-content: center;
        "
      >
        分类
      </div>
      <!-- 设置指定元素可以滚动但不显示滚动条overflow: hidden -->
      <!-- 高度为length计算出来的高度 -->
      <div style="overflow: hidden; height: 721px" id="areaContainer">
        <div
          v-for="(item, index) in categories"
          style="width: 100px; height: 50px"
          :key="item.id"
        >
          <div
            style="
              width: 100px;
              height: 52px;
              border: 1px solid red;
              display: flex;
              align-items: center;
              justify-content: center;
            "
            :style="{
              'border-bottom':
                index + 1 === categories.length ? '1px solid red' : 'none',
              'border-top': index === 0 ? 'none' : '1px solid red',
            }"
          >
            {{ item.value }}
          </div>
        </div>
      </div>
    </div>
    <!-- 固定x轴设置高度,值比508大一点,范围得自己调 -->
    <div id="container" style="flex: 1; height: 535px"></div>
  </div>
</template>
<script>
import moment from "moment";
import Highcharts from "@/utils/highcharts-gantt";
export default {
  data() {
    return {
      ganttData: [
        {
          name: "任务1",
          x: new Date("2022-12-01 09:00:00").getTime(),
          x2: new Date("2022-12-11 09:00:00").getTime(),
          y: 0,
        },
        {
          name: "任务2",
          x: new Date("2022-12-08 09:00:00").getTime(),
          x2: new Date("2022-12-10 19:20:40").getTime(),
          y: 1,
        },
        {
          name: "任务3",
          x: new Date("2022-12-06 09:00:00").getTime(),
          x2: new Date("2022-12-20 19:20:40").getTime(),
          y: 2,
        },
        {
          name: "任务4",
          x: new Date("2022-12-18 09:00:00").getTime(),
          x2: new Date("2022-12-22 19:20:40").getTime(),
          y: 10,
        },
        {
          name: "任务5",
          x: new Date("2022-12-05 09:00:00").getTime(),
          x2: new Date("2022-12-15 19:20:40").getTime(),
          y: 12,
        },
      ],
      categories: [
        {
          id: 1,
          value: "分类1",
        },
        {
          id: 2,
          value: "分类2",
        },
        {
          id: 3,
          value: "分类3",
        },
        {
          id: 4,
          value: "分类4",
        },
        {
          id: 5,
          value: "分类5",
        },
        {
          id: 6,
          value: "分类6",
        },
        {
          id: 7,
          value: "分类7",
        },
        {
          id: 8,
          value: "分类8",
        },
        {
          id: 9,
          value: "分类9",
        },
        {
          id: 10,
          value: "分类10",
        },
        {
          id: 11,
          value: "分类11",
        },
        {
          id: 12,
          value: "分类12",
        },
        {
          id: 13,
          value: "分类13",
        },
      ],
      areas: [
        {
          id: 11,
          value: "卷包车间",
          // length: 8
        },
        {
          id: 22,
          value: "异型车间",
          // length: 5
        },
        {
          id: 223,
          value: "异型车间1",
          // length: 5
        },
      ],
    };
  },
  mounted() {
    this.categories = this.categories.map((i) => ({
      ...i,
      checked: false,
    }));
    let month = "2022-12";
    const WEEKS = {
      0: "日",
      1: "一",
      2: "二",
      3: "三",
      4: "四",
      5: "五",
      6: "六",
    };
    Highcharts.setOptions({
      global: {
        useUTC: false, // 不使用utc时间
      },
      lang: {
        noData: "暂无数据",
      },
    });
    const gChart = Highcharts.ganttChart("container", {
      alignTicks: false,
      series: [
        {
          type: "gantt",
          name: "设备",
          data: this.ganttData,
          dataLabels: {
            enabled: true,
            format: "{point.name}",
          },
          tooltip: {
            pointFormatter: function () {
              return `<div>
                <span style="color:{point.color}">\u25CF</span> ${this.name}  
                <br />
                开始时间:${moment(this.x).format("YYYY-MM-DD HH:mm:ss")}
                <br />
                结束时间:${moment(this.x2).format("YYYY-MM-DD HH:mm:ss")}
              </div>`;
            },
          },
        },
      ],
      xAxis: [
        {
          min: moment(month).valueOf(),
          max: moment(month).endOf("month").valueOf(),
          gridLineEidth: 1,
          minTickInterval: 1000 * 60 * 60 * 24,
          currentDateIndicator: true,
          tickPixelInterval: 70,
          grid: {
            borderWidth: 1, // 右侧表头边框宽度
            cellHeight: 35, // 右侧日期表头高度
          },
          labels: {
            align: "center",
            formatter: function () {
              return `${WEEKS[moment(this.value).day()]}`;
            },
          },
        },
        {
          gridLineWidth: 1,
          minTickInterval: 1000 * 60 * 60 * 24,
          tickPixelInterval: 100,
          grid: {
            borderWidth: 1, // 右侧表头边框宽度
            cellHeight: 30, // 右侧日期表头高度
          },
          labels: {
            align: "center",
            formatter: function () {
              return `${moment(this.value).format("D")} `;
            },
          },
        },
      ],
      yAxis: {
        type: "category",
        grid: {
          columns: [
            {
              title: {
                text: "任务分类",
              },
              reversed: true,
              categories: this.categories,
              labels: {
                useHTML: true,
                formatter: function () {
                  var label = `
                <div style="display:flex;align-items:center">
                  <div class="checkbox" style="width:16px;height:16px;border:1px solid #444;margin-right:5px;cursor:pointer" id='${this.value.id}'>
                    <span
                      class="has-check"
                      style="opacity: 0;font-size:12px;padding-left:3px;">✔</span>
                  </div>
                  ${this.value.value}
                </div>`;
                  return label;
                },
              },
            },
          ],
        },
      },
      chart: {
        spacingLeft: 0,
        scrollablePlotArea: {
          minHeight: 741, // 52 * this.categories.length + 65(52是每个y轴label的高度,65是2个xAxis的高度),设置这个属性能在页面滚动时,头部固定
        },
      },
    });
    let areadiv = document.querySelector("#areaContainer");
    // 监听甘特图的滚动事件
    gChart.scrollingContainer.addEventListener("scroll", (e) => {
      // 给指定元素设置滚动距离
      areadiv.scrollTo({
        top: e.target.scrollTop,
        behavior: "smooth",
      });
    });

    const labelElements = document.querySelectorAll(
      "#container .highcharts-yaxis-labels .checkbox"
    );

    // 自定义复选框,给复选框添加点击事件
    labelElements.forEach((label) => {
      label.addEventListener(
        "click",
        (el) => {
          let element = el.target; // element是.checkbox元素
          const addClickElement = this.getParentElement(element, "checkbox");
          let id = "";
          if (element.classList.toString().indexOf("checkbox") !== -1) {
            id = element.getAttribute("id");
          }
          if (addClickElement) {
            id = addClickElement.getAttribute("id");
            element = addClickElement;
          }
          this.categories[id - 1].checked = !this.categories[id - 1].checked;
          element.style.background = this.categories[id - 1].checked
            ? "#0061ff"
            : "none";
          element.style.borderColor = this.categories[id - 1].checked
            ? "#0061ff"
            : "#444";
          element.querySelector(".has-check").style.opacity = 1;
          element.querySelector(".has-check").style.color = "#fff";
        },
        true
      );
    });

    // 监听鼠标滚轮事件
    // document.querySelector('#container').addEventListener('wheel', (el) => {
    //   console.log(el)
    // })
  },
  methods: {
    // 根据当前target元素找到指定className的父元素
    getParentElement(target, className) {
      let parent = target.parentElement;
      while (parent) {
        if (parent.classList.toString().indexOf(className) !== -1) {
          return parent;
        }
        parent = parent.parentElement;
      }
      return null;
    },
  },
};
</script>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/271920.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【代码混淆】react-native 代码混淆

​ 使用react native开发app&#xff0c;实现代码混淆的操作。 无论是加密还是运行时虚拟机&#xff0c;最后都可以通过执行时调试把代码反向生成出来原来的代码&#xff0c;虽然能抵御低端的黑客攻击&#xff0c;但是对高端黑客却形同虚设。 代码混淆是通过修改源代码结构和变…

【习题】运行Hello World工程

判断题 1. DevEco Studio是开发HarmonyOS应用的一站式集成开发环境。 正确(True)错误(False) 正确(True) 2. main_pages.json存放页面page路径配置信息。 正确(True)错误(False) 正确(True) 单选题 1. 在stage模型中&#xff0c;下列配置文件属于AppScope文件夹的是&am…

视频专访 | 每日互动刘宇:AI不止GC,更有TA

当前&#xff0c;“百模大战”已进入拼落地、拼应用的下半场&#xff0c;给千行百业带来了降本增效的巨大机遇。聚焦到品牌营销领域&#xff0c;大模型给行业带来了哪些改变&#xff1f;企业如何利用大模型优化数字化营销手段、提升数字化营销效果&#xff0c;最终驱动品牌实现…

嵌入式——I2C原理代码结合(干货)看图易懂

学习目标 理解I2C通讯原理理解I2C通讯过程中的信号理解软件I2C实现过程理解硬件I2C的工作内容学习内容 I2C通讯规则 I2C总线包括两根信号线:SDA(串行数据线)和SCL(串行时钟线)。这两根信号线共用一个总线,因此在总线上可以连接多个设备。在I2C总线上,每个设备都有一个唯…

微服务注册与发现——Eureka

文章目录 Eureka使用引用配置启动类标记访问微服务注册微服务工程添加引用增加配置启动类增加注解启动服务注册 Eureka Server集群部署修改配置文件启动多个eureka实例微服务注册到多个eureka实例 为Eureka Server添加用户认证引入spring-security配置关闭security的csrf&#…

C练习——水仙花数

“水仙花数”是指一个三位数&#xff0c;其每位数字的立方和等于该数本身。 例如&#xff1a;153是一个“水仙花数”&#xff0c;因为1531的三次方&#xff0b;5的三次方&#xff0b;3的三次方。 // 打印 100 - 999 的所有水仙花数 // 利用for循环控制100 - 999个数&#xff…

Exploring the Limits of Masked Visual Representation Learning at Scale论文笔记

论文名称&#xff1a;EVA: Exploring the Limits of Masked Visual Representation Learning at Scale 发表时间&#xff1a;CVPR2023 作者及组织&#xff1a;北京人工智能研究院&#xff1b;华中科技大学&#xff1b;浙江大学&#xff1b;北京理工大学 GitHub&#xff1a;http…

从公务员转行网络安全工程师,铁饭碗也比不过“金饽饽”。

前言 随着疫情的不断变化&#xff0c;影响力席卷大多数的行业&#xff0c;许多人也在这次疫情中失去了工作&#xff0c;或是收入与之前相比大打折扣&#xff0c;因此越来越多的人涌入到了考公或考事业单位的大潮之中。 考公是一场与实力与运气的battle&#xff0c;不到上岸的…

MS2244模拟开关可Pin to Pin兼容NJM2244

MS2244 是一款集成的视频开关&#xff0c;实现三输入视频或音频信号的三选一。可Pin to Pin兼容NJM2244。 芯片集成了 75Ω驱动电路&#xff0c;可以直接驱动电视监控器。芯片工作电压 5V&#xff5e;12V&#xff0c;带宽 10MHz&#xff0c;抗串扰 70dB (4.43MHz)。另外芯片还集…

NC(65)元数据增加字段

以报销单主表er_bxzb表为例&#xff0c;增加15个字段字段以及两个其他业务所需字段 1、先在er_bxzb增加字段 增加字段 alter table er_bxzb add no_invoice char(1) default(N);alter table er_bxzb add is_enabled_taxation_cloud char(1) default(N);alter table er_bxzb a…

SANSAN新鲜事|场站数字化避“坑”指南

场站如何定义 场站是指在某个特定的区域内&#xff0c;为了完成某个特定的任务而建立的一个或多个设施的集合。常见的场站涉及各行各业&#xff0c;比如电力行业的变电站、开闭所、配电房等&#xff1b;再比如燃气行业的门站、调压站、加气站等&#xff1b; 另外&#xff0c;还…

Ansys Speos | 3D Texture 车灯案例应用

Speos 3D Texture功能提供了一种解决方案&#xff0c;可以绕过 CAD 系统限制来设计和模拟数百万个小图案&#xff1a;pattern图案的分布类型和重复次数。3D Texture可用于设计照明系统&#xff0c;例如光导、车灯、亮度增强膜 &#xff08;BEF&#xff09; 和由数百万个几何元素…

Jmeter的性能测试

性能测试的概念 定义&#xff1a;软件的性能是软件的一种非功能特性&#xff0c;它关注的不是软件是否能够完成特定的功能&#xff0c;而是在完成该功能时展示出来的及时性。 由定义可知性能关注的是软件的非功能特性&#xff0c;所以一般来说性能测试介入的时机是在功能测试…

UGUI Panel的显示和隐藏优化

unity UI如何开启&#xff08;显示&#xff09;或者关闭&#xff08;隐藏&#xff09;Panel界面&#xff0c;相信大家都是知道的&#xff0c;但是如何做最好呢&#xff1f; 可能大家一般开启/关闭界面的方法就是直接SetActive吧。这样做通常是可以的&#xff0c;简答快速地解决…

leetcode——打家劫舍问题汇总

本章汇总一下leetcode中的打家劫舍问题&#xff0c;使用经典动态规划算法求解。 1、梦开始的地方——打家劫舍&#xff08;★&#xff09; 本题关键点就是不能在相邻房屋偷东西。 采用常规动态规划做法&#xff1a; 根据题意设定dp数组&#xff0c;dp[i]的含义为&#xff1a…

【rar压缩包密码】rar压缩包加密码怎么设置?

如何使用WinRAR加密压缩包&#xff1f;详细介绍WinRAR中的三种加密方法给大家。 方法一&#xff1a;加密 最简单的加密方法&#xff0c;就是在加密文件时输入想要设置的密码&#xff0c;完成加密和压缩了。 方法二&#xff1a;自动加密 普通的加密方式&#xff0c;需要我们加…

电影分线发行来势汹汹,行业新规到底利好谁?

年末的贺岁档&#xff0c;一直是各大影视公司的必争之地&#xff0c;但2023年却透露出一股不寻常的气息。 在10月份举办的第一届全国电影交易大会上&#xff0c;分线发行影片的机制被提出之后&#xff0c;贺岁档的多部影片启用了这一发行方式。 分线发行&#xff0c;简单来说…

sigmoid softmax优化

1.前言 最近在搞模型部署发现&#xff0c;推理速度不能满足我们需求&#xff0c;于是最近学习了优化算子技巧&#xff0c;学到了sigmoid&#xff0c;softmax算子优化&#xff0c;真的数学之美。2.sigmoid算子优化 一.算子优化图 我们根据sigmoid公式&#xff0c;我们进行求反…

JavaScript 中的双等号(==)和三等号(===)有何不同?何时使用它们?

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;JavaScript篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来JavaScript篇专栏内容:JavaScript-等号区别 目录 和 区别&#xff0c;分别在什么情况使用 一、等于操作符…

wxWidgets实战:wxGrid创建表单之复选框样式

1》 创建wxGrid WX_GRID* m_fieldsGrid m_fieldsGrid new WX_GRID( sbFields->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );m_fields new FIELDS_GRID_TABLE<SCH_FIELD>( this, aParent, m_fieldsGrid, m_symbol );FDC_SHOW_NAME FDC_SHOW_…