草庐IT

vue 甘特图 一行多条任务 可拖拽

丶凉雨拾忆 2023-03-28 原文

1、安装 highcharts

npm install highcharts --save

2、页面引用

// 引入
import Highcharts from 'highcharts/highcharts-gantt.src.js'
// 引入拖拽
import factory from 'highcharts/modules/draggable-points.js'
factory(Highcharts)

3、封装组件

<!--
 * @Descripttion: 新甘特图
 * @version: 0.0.1
 * @Author: PengShuai
 * @Date: 2023-01-12 13:20:44
 * @LastEditors: PengShuai
 * @LastEditTime: 2023-02-01 15:00:55
-->
<template>
  <div class="BaseNewGantt">
    <div id="container"></div>
  </div>
</template>

<script>
import Highcharts from 'highcharts/highcharts-gantt.src.js'
import factory from 'highcharts/modules/draggable-points.js'
factory(Highcharts)
export default {
  name: 'BaseNewGantt',
  data() {
    return {
      isShow: true,
      tableConfig: [],
    }
  },
  props: {
    // 甘特图配置
    ganttConfig: {
      type: Object,
      default: () => {
        return {
          data: [],
          columnsConfig: [],
        }
      },
    },
  },
  mounted() {},
  methods: {
    // 页面初始化
    init() {
      Highcharts.setOptions({
        global: {
          useUTC: false, // 不使用utc时间
        }, // 默认都是英文的,这里做了部分中文翻译
        lang: {
          noData: '暂无数据',
          months: [
            '一月',
            '二月',
            '三月',
            '四月',
            '五月',
            '六月',
            '七月',
            '八月',
            '九月',
            '十月',
            '十一月',
            '十二月',
          ],
          shortMonths: [
            '一月',
            '二月',
            '三月',
            '四月',
            '五月',
            '六月',
            '七月',
            '八月',
            '九月',
            '十月',
            '十一月',
            '十二月',
          ],
          weekdays: ['日', '一', '二', '三', '四', '五', '六'],
          buttons: [
            { type: 'month', count: 1, text: '月' },
            { type: 'month', count: 3, text: '季度' },
            { type: 'month', count: 6, text: '半年' },
            { type: 'ytd', text: 'YTD' },
            { type: 'year', count: 1, text: '年' },
            { type: 'all', text: '所有' },
          ],
          rangeSelectorZoom: '范围',
        },
      })

      this.getGantt()
    },
    getGantt() {
      const _this = this
      const day = 1000 * 60 * 60 * 24
      const map = Highcharts.map
      // 获取数据源
      let series = this.ganttConfig.data
      // 左侧表格配置
      this.columnsConfig = []
      if (this.ganttConfig.tableConfig.length > 0) {
        this.ganttConfig.tableConfig.forEach((item) => {
          let obj = {
            title: {
              text: item.title,
            },
            categories: map(series, function (s) {
              return s[item.labels]
            }),
          }
          this.columnsConfig.push(obj)
        })
      }
      Highcharts.ganttChart('container', {
        plotOptions: {
          series: {
            animation: true,
            dragDrop: {
              draggableX: true, // 是否横向拖动
              draggableY: false,  // 是否纵向拖动
              dragPrecisionX: day,
            },
            dataLabels: {
              enabled: true,
              format: '{point.title}',
              style: {
                cursor: 'default',
                opacity: _this.isShow ? 0 : 1,
                pointerEvents: 'none',
              },
            },
            allowPointSelect: true,
            point: {
              events: {
                dragStart: _this.onDragStart,
                drag: _this.onDrag,
                drop: _this.onDrop,
                select: _this.onHandleSelect,
              },
            },
          },
        },
        yAxis: {
          type: 'category',
          grid: {
            enabled: true,
            borderColor: 'rgba(0,0,0,0.3)',
            borderWidth: 1,
            columns: _this.columnsConfig,
          },
        },
        xAxis: [
          {
            currentDateIndicator: true,
            grid: {
              borderWidth: 1, // 右侧表头边框宽度
              cellHeight: 0, // 右侧日期表头高度
            },
            labels: {
              format: '{value:%d}日',
            },
          },
          {
            labels: {
              format: '{value:%Y年-%m月}',
            },
          },
        ],
        // 提示信息
        tooltip: {
          formatter: function () {
            return `<div>
              ${this.point.title}<br/>
              开始时间: ${_this.$library.common.formatDate(
                new Date(this.point.start),
                'YYYY-MM-DD',
              )}<br/>
              结束时间: ${_this.$library.common.formatDate(
                new Date(this.point.end),
                'YYYY-MM-DD',
              )}<br/>
              </div>`
          },
        },
        navigator: {
          enabled: true,
          series: {
            type: 'gantt',
            pointPlacement: 0.5,
            pointPadding: 0.25,
          },
          yAxis: {
            min: 0,
            max: 6,
            reversed: true,
            categories: [],
          },
        },
        series: series,
        // 显示滚动条
        scrollbar: {
          enabled: true,
        },
        // 顶部筛选按钮
        rangeSelector: {
          enabled: true,
          selected: 0,
          buttons: [
            { type: 'month', count: 1, text: '月' },
            { type: 'month', count: 3, text: '季度' },
            { type: 'month', count: 6, text: '半年' },
            { type: 'ytd', text: 'YTD' },
            { type: 'year', count: 1, text: '年' },
            { type: 'all', text: '所有' },
          ],
        },
        //   // 去掉右下角版权信息
        credits: {
          enabled: false,
        },
      })
    },
    // 拖动开始
    onDragStart(e) {},
    // 拖动
    onDrag(e) {},
    // 拖动停止
    onDrop(e) {
      this.$emit('onDragStop', e.target.options)
    },
    // 选择事件
    onHandleSelect(e) {
      this.$emit('onHandleSelect', e.target.options)
      console.log(e)
    },
    // 是否显示标题
    onShowTitle() {
      // 标题过长 隐藏 更改文字透明度 
      this.isShow = !this.isShow
      // 重新加载
      this.getGantt()
    },
  },
}
</script>

<style lang="less" scoped>
.BaseNewGantt {
  height: calc(100% - 70px);
  overflow: auto;
}
</style>

4、组件使用

<base-gantt
  ref="gantt"
  :ganttConfig="ganttConfig"
  @onDragStop="onDragStop"
  @onHandleSelect="onHandleSelect">
</base-gantt>

data中配置

   // 甘特图配置
    ganttConfig: {
      // 数据源
      data: [],
      // 左侧表格列配置
      tableConfig: [
        {
          title: '设备名称',
          labels: 'machineName',
        },
        {
          title: '设备编码',
          labels: 'machineNo',
        },
      ],
    },

事件

// 拖动停止
onDragStop(option) {},
// 甘特图选中
onHandleSelect(option) {
  this.selectGanttRowData = option
},

5、实例

6、官网地址

https://www.hcharts.cn/
演示地址
https://www.hcharts.cn/demo/gantt

有关vue 甘特图 一行多条任务 可拖拽的更多相关文章

  1. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  2. ruby - 如何使用 RSpec::Core::RakeTask 创建 RSpec Rake 任务? - 2

    如何使用RSpec::Core::RakeTask初始化RSpecRake任务?require'rspec/core/rake_task'RSpec::Core::RakeTask.newdo|t|#whatdoIputinhere?endInitialize函数记录在http://rubydoc.info/github/rspec/rspec-core/RSpec/Core/RakeTask#initialize-instance_method没有很好的记录;它只是说:-(RakeTask)initialize(*args,&task_block)AnewinstanceofRake

  3. 计算机毕业设计ssm+vue基本微信小程序的小学生兴趣延时班预约小程序 - 2

    项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU

  4. ruby-on-rails - Rake 任务仅调用一次时执行两次 - 2

    我写了一个非常简单的rake任务来尝试找到这个问题的根源。namespace:foodotaskbar::environmentdoputs'RUNNING'endend当在控制台中执行rakefoo:bar时,输出为:RUNNINGRUNNING当我执行任何rake任务时会发生这种情况。有没有人遇到过这样的事情?编辑上面的rake任务就是写在那个.rake文件中的所有内容。这是当前正在使用的Rakefile。requireFile.expand_path('../config/application',__FILE__)OurApp::Application.load_tasks这里

  5. ruby-on-rails - 在 RSpec 中,如何以任意顺序期望具有不同参数的多条消息? - 2

    RSpec似乎按顺序匹配方法接收的消息。我不确定如何使以下代码工作:allow(a).toreceive(:f)expect(a).toreceive(:f).with(2)a.f(1)a.f(2)a.f(3)我问的原因是a.f的一些调用是由我的代码的上层控制的,所以我不能对这些方法调用添加期望。 最佳答案 RSpecspy是测试这种情况的一种方式。要监视一个方法,用allowstub,除了方法名称之外没有任何约束,调用该方法,然后expect确切的方法调用。例如:allow(a).toreceive(:f)a.f(2)a.f(1)

  6. ruby-on-rails - 在 Rails 中更高效地查找或创建多条记录 - 2

    我有一个应用需要发送用户事件邀请。当用户邀请friend(用户)参加事件时,如果尚不存在将用户连接到该事件的新记录,则会创建该记录。我的模型由用户、事件和events_user组成。classEventdefinvite(user_id,*args)user_id.eachdo|u|e=EventsUser.find_or_create_by_event_id_and_user_id(self.id,u)e.save!endendend用法Event.first.invite([1,2,3])我不认为以上是完成我的任务的最有效方法。我设想了一种方法,例如Model.find_or_cr

  7. ruby - 帮助使用 Ruby 中的 "Whenever"gem 来执行 cron 任务 - 2

    我以前没有使用过cron,所以我不能确定我这样做是对的。我想要自动化的任务似乎没有运行。我在终端中执行了这些步骤:sudogeminstall每当切换到应用程序目录无论何时。(这创建了文件schedule.rb)我将此代码添加到schedule.rb:every10.minutesdorunner"User.vote",environment=>"development"endevery:hourdorunner"Digest.rss",:environment=>"development"end我将此代码添加到deploy.rb:after"deploy:symlink","depl

  8. ruby - 在 rake 任务中运行 capybara - 2

    如何在Rake任务中运行Capybara功能?例如:访问('http://google.com')谢谢! 最佳答案 在任务中尝试这样的事情:require'capybara'require'capybara/dsl'Capybara.current_driver=:seleniumBrowser=Class.new{includeCapybara::DSL}page=Browser.new.pagepage.visit("http://www.google.com")puts(page.html)

  9. ruby - 在 Rakefile 中动态生成 Rake 测试任务(基于现有的测试文件) - 2

    我正在根据Rakefile中的现有测试文件动态生成测试任务。假设您有各种以模式命名的单元测试文件test_.rb.所以我正在做的是创建一个以“测试”命名空间内的文件名命名的任务。使用下面的代码,我可以用raketest:调用所有测试require'rake/testtask'task:default=>'test:all'namespace:testdodesc"Runalltests"Rake::TestTask.new(:all)do|t|t.test_files=FileList['test_*.rb']endFileList['test_*.rb'].eachdo|task|n

  10. ruby - 如何使用 Ruby 从 CSV 中删除一行 - 2

    给定以下CSV文件,您将如何删除列“foo”中包含单词“true”的所有行?Date,foo,bar2014/10/31,true,derp2014/10/31,false,derp我有一个可行的解决方案,但它需要制作一个辅助CSV对象csv_no_foo@csv=CSV.read(@csvfile,headers:true)#http://bit.ly/1mSlqfA@headers=CSV.open(@csvfile,'r',:headers=>true).read.headers#MakeanewCSV@csv_no_foo=CSV.new(@headers)@csv.eachd

随机推荐