欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue3使用vis繪制甘特圖制作timeline可拖動(dòng)時(shí)間軸及時(shí)間軸中文化(推薦)

 更新時(shí)間:2023年02月16日 15:11:03   作者:林啾啾  
這篇文章主要介紹了vue3使用vis繪制甘特圖制作timeline可拖動(dòng)時(shí)間軸,時(shí)間軸中文化,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

前言:參考文檔文章

vis官方配置文檔:文檔地址
參考使用文章:文章地址

一、實(shí)現(xiàn)效果:

在這里插入圖片描述

二、安裝插件及依賴:

cnpm install -S vis-linetime
cnpm install -S vis-data
cnpm install -S moment

三、封裝組件:

下端時(shí)間軸單獨(dú)封裝成組件

在這里插入圖片描述

在這里插入圖片描述

1.html部分:

<template>
  <div class="visGantt" ref="visGanttDom"></div>
</template>

2.引入依賴:

import { DataSet } from 'vis-data/peer'
import { dateFormat } from '@/util' //封裝的時(shí)間格式化函數(shù),如下所示
import { Timeline } from 'vis-timeline/peer'
import 'vis-timeline/styles/vis-timeline-graph2d.css'
const moment = require('moment')

時(shí)間格式化函數(shù):

export function dateFormat(date, fmt) { //date是日期,fmt是格式
    let o = {
        'M+': date.getMonth() + 1, // 月份
        'd+': date.getDate(), // 日
        'H+': date.getHours(), // 小時(shí)
        'h+': date.getHours(), // 小時(shí)
        'm+': date.getMinutes(), // 分
        's+': date.getSeconds(), // 秒
        'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
        S: date.getMilliseconds() // 毫秒
    }
    if (/(y+)/.test(fmt)) {
        fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
    }
    for (var k in o) {
        if (new RegExp('(' + k + ')').test(fmt)) {
            fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)))
        }
    }
    return fmt
}

3.父組件傳入數(shù)據(jù):

let props = defineProps({
  ganntData: { // 初始傳入數(shù)據(jù)
    type: Object,
    default: () => {}
  },
  ganntHistoryData: { // 全部的歷史數(shù)據(jù),為了實(shí)現(xiàn)撤銷上一步
    type: Object,
    default: () => {}
  }
})

4.js部分全部配置

配置項(xiàng)參考官方文檔,僅注釋解釋個(gè)別方法。

<script setup>
import { ref, defineProps, watch, nextTick, defineEmits } from 'vue'
import { DataSet } from 'vis-data/peer'
import { dateFormat } from '@/util'
import { Timeline } from 'vis-timeline/peer'
import 'vis-timeline/styles/vis-timeline-graph2d.css'
const moment = require('moment')
let props = defineProps({
  ganntData: {
    type: Object,
    default: () => {}
  },
  ganntHistoryData: {
    type: Object,
    default: () => {}
  }
})
let timeline = ref(null)
watch(
  props.ganntData,
  (newVal) => {
    if (newVal && newVal[0].trackTimeWindows && newVal[0].trackTimeWindows.length > 0) {
      nextTick(() => {
        initChart()
        checkTimeConflict()
      })
    }
  },
  {
    immediate: true,
    deep: true
  }
)
const computedData = () =>{
  const trackTimeWindows = []
  const timeWindows = []
  props.ganntData[0].trackTimeWindows.forEach(
    (trackTimeWindow, trackTimeWindowIndex) => {
      // 項(xiàng)目類別數(shù)組
      trackTimeWindows.push({
        content: trackTimeWindow.deviceId,
        id: `${trackTimeWindow.deviceId}-${trackTimeWindowIndex}-trackTimeWindows`,
        value: trackTimeWindowIndex + 1,
        className: `visGantt-item${trackTimeWindowIndex % 10}`
      })
      // 項(xiàng)目時(shí)間數(shù)組
      trackTimeWindow.timeWindows.forEach((timeWindow, timeWindowIndex) => {
        timeWindows.push({
          start: new Date(timeWindow.startTime),
          startTime: timeWindow.startTime,
          end: new Date(timeWindow.stopTime),
          stopTime: timeWindow.stopTime,
          topTime: timeWindow.topTime,
          group: `${trackTimeWindow.deviceId}-${trackTimeWindowIndex}-trackTimeWindows`,
          className: `visGantt-item${trackTimeWindowIndex % 10}`,
          id: `${trackTimeWindow.deviceId}`,
          deviceId: trackTimeWindow.deviceId
        })
      })
    }
  )
  return {
    trackTimeWindows,
    timeWindows
  }
}
const visGanttDom = ref(null)
let historyDataArray = ref([])
const emit = defineEmits()
// 選擇某個(gè)item
let onSelect = (properties) => {
  emit('selectItem', properties.items[0])
}
const initChart = ()=> {
  const { timeWindows, trackTimeWindows } = computedData()
  const groups = new DataSet(trackTimeWindows)
  const items = new DataSet(timeWindows)
  let container = visGanttDom.value
  if (container.firstChild) {
    container.removeChild(container.firstChild)
  }
  // 甘特圖配置
  const options = {
    groupOrder: function(a, b) {
      return a.value - b.value
    },
    groupOrderSwap: function(a, b, groups) {
      var v = a.value
      a.value = b.value
      b.value = v
    },
    height: '23.8vh', // 高度
    verticalScroll: false, // 豎向滾動(dòng)
    orientation: 'top', // 時(shí)間軸位置
    margin: {
      axis: 1,
      item: {
        horizontal: 0,
        vertical: 20
      }
    },
    editable: {
      updateTime: true,
      updateGroup: false
    },
    multiselect: true,
    moment: function(date) {
      return moment(date).utc('+08:00')
    },
    groupHeightMode: 'fixed',
    // min: new Date(startTime.value), // 最小可見范圍
    tooltip: {
      followMouse: true,
      overflowMethod: 'cap',
      template: (originalItemData, parsedItemData) => {
        // 鼠標(biāo)hover時(shí)顯示樣式
        return `<div>
          <p>
            <span>項(xiàng)目名稱:</span>
            <span>${originalItemData.deviceId}</span>
          </p><br/>
          <p>
            <span>開始時(shí)間:</span>
            <span>${dateFormat(parsedItemData.start, 'yyyy-MM-dd')}</span>
          </p><br/>
            <span>結(jié)束時(shí)間:</span>
            <span>${dateFormat(parsedItemData.end, 'yyyy-MM-dd')}</span>
          </p>
        </div>`
      }
    },
    tooltipOnItemUpdateTime: {
      template: (item) => {
      // 鼠標(biāo)拖動(dòng)時(shí)顯示樣式
        return `<div>
            <span>開始時(shí)間:${dateFormat(item.start, 'yyyy-MM-dd')}</span>
            <span>\n</span>
            <span>結(jié)束時(shí)間:${dateFormat(item.end, 'yyyy-MM-dd')}</span>
        </div>`
      }
    },
    locale: moment.locale('zh-cn'), // 時(shí)間軸國(guó)際化
    showCurrentTime: false,
    selectable: true,
    zoomMin: 1728000000,
    zoomMax: 315360000000,
    // showTooltips: false,
    // autoResize: false,
    snap: function(date, scale, step) {
      var day = 60 * 60 * 1000 * 24
      return Math.round(date / day) * day
    },
    // 移動(dòng)時(shí)返回函數(shù)
    onMove: function(item, callback) {
      // 深拷貝一下,不能直接修改父組件數(shù)據(jù)
      historyDataArray.value = JSON.parse(JSON.stringify(props.ganntHistoryData))
      let historyData = []
      // props.ganntHistoryData是全部的歷史數(shù)據(jù),historyData 是取上一步的數(shù)據(jù)
      historyData = JSON.parse(JSON.stringify(props.ganntHistoryData[props.ganntHistoryData.length - 1]))
      // 更改一下格式
      historyData[0].trackTimeWindows.forEach((eachItem)=>{
        if (eachItem.deviceId === item.deviceId) {
          if (!item.start || !item.end) {
            return
          }
          eachItem.timeWindows[0].startTime = item.start
          eachItem.timeWindows[0].stopTime = item.end
        }
      })
      historyDataArray.value.push(historyData)
      // 更新一下ganntHistoryData歷史數(shù)據(jù)
      emit('update:ganntHistoryData', historyDataArray.value)
      callback(item)
    },
    onMoving: function(item, callback) {
      // 移動(dòng)時(shí)間軸時(shí)不顯示tooltip提示框
      let tooltipDom = document.getElementsByClassName('vis-tooltip')
      tooltipDom[0].style.visibility = 'hidden'
      callback(item)
    }
  }
  timeline.value = new Timeline(container)
  timeline.value.redraw()
  timeline.value.setOptions(options)
  timeline.value.setGroups(groups)
  timeline.value.setItems(items)
  timeline.value.on('select', onSelect)
}
</script>

四、父組件調(diào)用

1.引入子組件

<div v-loading="loading"> // loading是為了有個(gè)加載效果,為了美觀
	<time-line 
	:ganntData="ganntData"  // 原始數(shù)據(jù)
	v-model:ganntHistoryData="ganntHistoryData"  // 歷史數(shù)據(jù)
	@selectItem="timelineSelected" //選擇事件
	>
	</time-line>
</div>
import TimeLine from '@/components/modules/planControl/TimeLine'

2.初始數(shù)據(jù)

let props = defineProps({
 // 因?yàn)檫@個(gè)父組件是通過點(diǎn)擊進(jìn)來(lái)的,所以有傳入的數(shù)據(jù),也可以直接賦值ganntData 數(shù)據(jù),可以省略watch里面的轉(zhuǎn)格式
  conflictList: {
    type: Array,
    default: null
  }
})
const ganntData = reactive([
  {
    name: 'confilct',
    trackTimeWindows: [
    ]
  }
])

const ganntHistoryData = ref([])

// 傳入數(shù)據(jù)變化時(shí)為ganntData和ganntHistoryData賦值。
watch(
  () => props.conflictList, (newValue) => {
    ganntData[0].trackTimeWindows.length = 0
    newValue.forEach(element => {
      ganntData[0].trackTimeWindows.push({
        deviceId: element.content,
        timeWindows: [
          {
            startTime: element.startTime,
            stopTime: element.stopTime
          }
        ]
      })
    })
    // 記錄操作歷史
    ganntHistoryData.value.length = 0
    ganntHistoryData.value.push(ganntData)
  },
  {
    deep: true,
    immediate: true
  }
)

原數(shù)據(jù)(省略部分未使用參數(shù)):

[
    {
        "id": 1,
        "content": "xxxxxxxxxxxxxx計(jì)劃1",
        "time": "2023.08~10",
        "startTime": "2023-08-09",
        "stopTime": "2023-10-20"
    },
    {
        "id": 2,
        "content": "xxxxxxxxxxxxxx計(jì)劃2",
        "time": "2023.09~11",
        "startTime": "2023-09-09",
        "stopTime": "2023-11-1"
    },
    {
        "id": 3,
        "content": "xxxxxxxxxxxxxx計(jì)劃3",
        "time": "2023.08~10",
        "startTime": "2023-08-20",
        "stopTime": "2023-10-1"
    }
]

3.父組件按鈕及事件

僅展示原始圖、撤銷事件。

    <div>
      <div>
        <el-button @click="reset()">原始圖</el-button>
        <el-button @click="preNode()">撤銷</el-button>
        <el-button>一鍵調(diào)整</el-button>
      </div>
      <div>
        <el-button>取消</el-button>
        <el-button>保存并退出</el-button>
      </div>
    </div>

回歸原始圖事件:
大致思路:先把ganntData清空,將拿到的props.conflictList里的數(shù)據(jù)賦值給ganntData,再把ganntData的數(shù)據(jù)push進(jìn)ganntHistoryData中

 // showResetTip 是顯示一個(gè)“已回到初始狀態(tài)”的提示框,可以自己封裝或者使用組件,此處不展示
const showResetTip = ref(false)
const loading = ref(false)
const reset = () => {
  // loading是加載效果
  loading.value = true
  ganntData[0].trackTimeWindows.length = 0
  props.conflictList.forEach(element => {
    ganntData[0].trackTimeWindows.push({
      deviceId: element.content,
      timeWindows: [
        {
          startTime: element.startTime,
          stopTime: element.stopTime
        }
      ]
    })
  })
  showResetTip.value = true
  ganntHistoryData.value.splice(0)
  ganntHistoryData.value.push(ganntData)
  setTimeout(() => {
    showResetTip.value = false
    loading.value = false
  }, 1000)
}

撤銷事件:
大致思路:拿到子組件返回的ganntHistoryData歷史數(shù)據(jù)數(shù)組,刪掉最后一組數(shù)據(jù)后:
如果歷史數(shù)據(jù)數(shù)組的長(zhǎng)度<= 1,代表再撤銷就回到原始狀態(tài)了,那就直接調(diào)用reset()回到原始圖;
否則,將ganntHistoryData刪掉最后一組數(shù)據(jù)后的ganntHistoryDataClone最后一組值賦給ganntData,

const preNode = () => {
  // loading是加載效果
  loading.value = true
  let ganntHistoryDataClone = []
  ganntHistoryDataClone = JSON.parse(JSON.stringify(ganntHistoryData.value))
  ganntHistoryDataClone.splice(ganntHistoryDataClone.length - 1, 1)
  if (ganntHistoryDataClone.length <= 1) {
    reset()
  } else {
    ganntData[0] = ganntHistoryDataClone[ganntHistoryDataClone.length - 1][0]
    ganntHistoryData.value = JSON.parse(JSON.stringify(ganntHistoryDataClone))
  }
  setTimeout(() => {
    loading.value = false
  }, 1000)
}

到此這篇關(guān)于vue3使用vis繪制甘特圖制作timeline可拖動(dòng)時(shí)間軸,時(shí)間軸中文化的文章就介紹到這了,更多相關(guān)vue3用vis繪制甘特圖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue組件間通信的實(shí)現(xiàn)方法講解

    Vue組件間通信的實(shí)現(xiàn)方法講解

    組件是vue.js最強(qiáng)大的功能之一,而組件實(shí)例的作用域是相互獨(dú)立的,這就意味著不同組件之間的數(shù)據(jù)無(wú)法相互進(jìn)行直接的引用,所以組件間的相互通信是非常重要的
    2023-01-01
  • uni-app中App與webview雙向?qū)崟r(shí)通信詳細(xì)代碼示例

    uni-app中App與webview雙向?qū)崟r(shí)通信詳細(xì)代碼示例

    在移動(dòng)應(yīng)用開發(fā)中,uni-app是一個(gè)非常流行的框架,它允許開發(fā)者使用一套代碼庫(kù)構(gòu)建多端應(yīng)用,包括H5、小程序、App等,這篇文章主要給大家介紹了關(guān)于uni-app中App與webview雙向?qū)崟r(shí)通信的相關(guān)資料,需要的朋友可以參考下
    2024-07-07
  • Vue中如何把hash模式改為history模式

    Vue中如何把hash模式改為history模式

    這篇文章主要介紹了Vue中如何把hash模式改為history模式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • vue更新數(shù)據(jù)卻不渲染頁(yè)面的解決

    vue更新數(shù)據(jù)卻不渲染頁(yè)面的解決

    這篇文章主要介紹了vue更新數(shù)據(jù)卻不渲染頁(yè)面的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • vue+rem自定義輪播圖效果

    vue+rem自定義輪播圖效果

    這篇文章主要為大家詳細(xì)介紹了vue+rem自定義輪播圖效果,手指觸摸左滑和右滑,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • vue實(shí)現(xiàn)購(gòu)物車功能(親測(cè)可用)

    vue實(shí)現(xiàn)購(gòu)物車功能(親測(cè)可用)

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)購(gòu)物車功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • el-tree樹組件懶加載(后端上千條數(shù)據(jù)前端進(jìn)行處理)

    el-tree樹組件懶加載(后端上千條數(shù)據(jù)前端進(jìn)行處理)

    本文主要介紹了el-tree樹組件懶加載(后端上千條數(shù)據(jù)前端進(jìn)行處理),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • 基于vue.js實(shí)現(xiàn)圖片輪播效果

    基于vue.js實(shí)現(xiàn)圖片輪播效果

    這篇文章主要為大家詳細(xì)介紹了基于vue.js實(shí)現(xiàn)圖片輪播效果,vue如何實(shí)現(xiàn)輪播圖效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • Vue中的生命周期介紹

    Vue中的生命周期介紹

    這篇文章介紹了Vue中的生命周期,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • v-for中動(dòng)態(tài)校驗(yàn)el-form表單項(xiàng)的實(shí)踐

    v-for中動(dòng)態(tài)校驗(yàn)el-form表單項(xiàng)的實(shí)踐

    在項(xiàng)目開發(fā)中,我們經(jīng)常會(huì)遇到表單保存的功能,本文主要介紹了v-for中動(dòng)態(tài)校驗(yàn)el-form表單項(xiàng)的實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧<BR>
    2022-05-05

最新評(píng)論