highcharts的甘特图,在页面出现滚动条时,xAixs轴固定

效果演示:
请添加图片描述
主要属性:

chart: {
  scrollablePlotArea: {
    minHeight: 741, // 设置这个属性能在页面滚动时,头部固定
  },
},

示例图中的功能除了设置头部固定外,自定义了复选框。因为highcharts中使用formatter自定义html内容,不能渲染html表单相关标签,屏蔽了表单元素,而又有复选框的需求,故自定义了复选框,并找到对应复选框元素绑定点击事件。

示例图完整的代码解析:

<template>
  <div id="container" style="width: 100vw; height: 500px"></div>
</template>

<script>
import moment from "moment";
import Highcharts from "@/utils/highcharts-gantt.js"; // https://code.hcharts.cn/gantt/highcharts-gantt.js
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,
        },
      ],
      scatterData: [
        {
          name: "计划1",
          x: new Date("2022-12-06 09:00:00").getTime(),
          y: 0,
        },
        {
          name: "计划2",
          x: new Date("2022-12-05 09:00:00").getTime(),
          y: 1,
        },
        {
          name: "计划3",
          x: new Date("2022-12-06 09:00:00").getTime(),
          y: 2,
        },
        {
          name: "计划4",
          x: new Date("2022-12-12 09:00:00").getTime(),
          y: 12,
        },
        {
          name: "计划5",
          x: new Date("2022-12-05 09:00:00").getTime(),
          y: 10,
        },
      ],
      scatterData2: [
        {
          name: "12",
          x: new Date("2022-12-01 09:00:00").getTime(),
          y: 0,
        },
        {
          name: "33",
          x: new Date("2022-12-02 09:00:00").getTime(),
          y: 1,
        },
        {
          name: "1065",
          x: new Date("2022-12-03 09:00:00").getTime(),
          y: 2,
        },
        {
          name: "123",
          x: new Date("2022-12-14 09:00:00").getTime(),
          y: 2,
        },
        {
          name: "4",
          x: new Date("2022-12-05 09:00:00").getTime(),
          y: 11,
        },
        {
          name: "4",
          x: new Date("2022-12-06 09:00:00").getTime(),
          y: 2,
        },
        {
          name: "4",
          x: new Date("2022-12-07 09:00:00").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",
        },
      ],
    };
  },
  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: "暂无数据",
      },
    });
    Highcharts.ganttChart("container", {
      series: [
        {
          type: "gantt",
          name: "设备",
          data: this.ganttData,
          dataLabels: {
            enabled: true,
            format: "{point.name}",
          },
          tooltip: {
            pointFormatter: function () {
              // console.log(this);
              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>`;
            },
          },
        },
        {
          type: "scatter",
          name: "计划",
          data: this.scatterData,
          stickyTracking: false, // 粘性跟踪默认是 true,可以去掉注释查看效果
          marker: {
            enabled: true,
            symbol: "circle",
            radius: 6,
          },
          tooltip: {
            pointFormat:
              '<span style="color:{point.color}">\u25CF</span> <b>{point.name}</b><br/>',
          },
          findNearestPointBy: "xy",
        },
        {
          type: "scatter",
          name: "任务",
          data: this.scatterData2,
          stickyTracking: false,
          enableMouseTracking: false, // 隐藏他的tooltip
          marker: {
            enabled: false, // 不显示散点图的图案
            states: {
              hover: {
                enabled: false,
              },
            },
          },
          tooltip: {
            pointFormat:
              '<span style="color:{point.color}">\u25CF</span> <b>{point.name}</b><br/>',
          },
          dataLabels: {
            enabled: true,
            align: "center",
            verticalAlign: "middle",
            crop: false,
            overflow: "none",
            style: {
              fontWeight: 300,
              fontSize: "14px",
              color: "#333",
              textOutline: "1px contrast",
            },
            formatter: function () {
              return this.point.name;
            },
          },
        },
      ],
      xAxis: [
        {
          // maxPadding: 0,
          // minPadding: 0,
          // startOnTick: true,
          // endOnTick: true,
          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()]}`;
            },
          },
        },
        {
          // maxPadding: 0,
          // minPadding: 0,
          // startOnTick: true,
          // endOnTick: true,
          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: {
        // max: 500,
        // scrollbar: {
        //   enabled: true,
        // },
        type: "category",
        categories: this.categories,
        reversed: true,
        title: {
          text: "任务分类",
        },
        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: {
        scrollablePlotArea: {
          minHeight: 741, // 52 * this.categories.length + 65(52是每个y轴label的高度,65是2个xAxis的高度),设置这个属性能在页面滚动时,头部固定
        },
      },
    });

    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
      );
    });
  },
  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>

<style scoped></style>

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值