| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- <template>
- <div class="process">
- <svg
- viewBox="0 0 1440 780"
- @click.stop="details({ X: -10000, Y: -10000, name: '', sTime: 0, eTime: 0 })"
- >
- <defs>
- <!-- 24小时文字样式 -->
- <g id="default">
- <line
- x1="0"
- y1="0"
- x2="1440"
- y2="0"
- stroke=" #195481"
- stroke-width="1"
- />
- <rect
- x="0"
- y="0"
- width="1440"
- height="29"
- fill="#2469C9"
- fill-opacity="0.2"
- />
- <line
- x1="0"
- y1="30"
- x2="1440"
- y2="30"
- stroke=" #195481"
- stroke-width="1"
- />
- <g
- v-for="(item, index) in time"
- :key="index"
- >
- <g v-if="index < 24">
- <text
- :x="index * 60 + 15"
- y="20"
- font-size="14"
- fill="white"
- >
- {{ index === 23 ? '00:00' : item + ':00' }}
- </text>
- <line
- :x1="index * 60"
- y1="0"
- :x2="index * 60"
- y2="780"
- stroke="#195481"
- stroke-width="1"
- />
- </g>
- <line
- v-else
- :x1="index * 60"
- y1="0"
- :x2="index * 60"
- y2="780"
- stroke="#195481"
- stroke-width="1"
- />
- </g>
- </g>
- <!-- tip -->
- <g id="tip">
- <image
- href="./img/1.png"
- width="130"
- height="80"
- />
- <text
- fill="white"
- y="28"
- x="15"
- font-size="13"
- >
- {{ tipData.name }}
- </text>
- <text
- fill="white"
- y="48"
- x="15"
- font-size="12"
- >
- 开始时间:{{ tipData.st }}
- </text>
- <text
- fill="white"
- y="68"
- x="15"
- font-size="12"
- >
- 结束时间:{{ tipData.et }}
- </text>
- </g>
- </defs>
- <!-- 24小时 -->
- <use xlink:href="#default" />
- <!-- 工序格 -->
- <rect
- v-for="(item, index) in planDetail"
- :key="index"
- :x="item.X"
- :y="item.Y"
- rx="2"
- ry="2"
- :width="item.width"
- height="20"
- :fill="colorDic[item.name!]"
- @click.stop="details(item)"
- />
- <!-- tips -->
- <use
- xlink:href="#tip"
- :x="tipData.X"
- :y="tipData.Y"
- />
- </svg>
- </div>
- </template>
- <script setup lang='ts'>
- import { onMounted, ref, watch } from 'vue'
- import { format } from 'date-fns'
- interface Item {
- name: string,
- X?: number,
- Y?: number,
- width?: number,
- sTime: number,
- eTime: number,
- st?: string,
- et?: string
- }
- const props = withDefaults(defineProps<{
- data?: Item[]
- }>(), {
- data: () => [
- {
- name: '地质钻探',
- sTime: 1730795400000,
- eTime: 1730797200000
- },
- {
- name: '开挖(装药)',
- sTime: 1730795400000,
- eTime: 1730797200000
- },
- {
- name: '通风除尘',
- sTime: 1730797200000,
- eTime: 1730800800000
- },
- {
- name: '装渣',
- sTime: 1730795400000,
- eTime: 1730797200000
- },
- {
- name: '运渣',
- sTime: 1730795400000,
- eTime: 1730797200000
- },
- {
- name: '拱架安装',
- sTime: 1730795400000,
- eTime: 1730797200000
- },
- {
- name: '锚杆安装',
- sTime: 1730795400000,
- eTime: 1730797200000
- },
- {
- name: '湿喷混凝土',
- sTime: 1730795400000,
- eTime: 1730797200000
- },
- {
- name: '超前支护',
- sTime: 1730795400000,
- eTime: 1730797200000
- },
- {
- name: '仰拱作业',
- sTime: 1730795400000,
- eTime: 1730797200000
- },
- {
- name: '防排水',
- sTime: 1730795400000,
- eTime: 1730797200000
- },
- {
- name: '二衬作业',
- sTime: 1730795400000,
- eTime: 1730797200000
- },
- {
- name: '养护',
- sTime: 1730795400000,
- eTime: 1730797200000
- },
- {
- name: '水电槽',
- sTime: 1730795400000,
- eTime: 1730797200000
- }
- ]
- })
- const colorDic: Object = {
- 地质钻探: '#6fff8c',
- '开挖(装药)': '#439bff',
- 通风除尘: '#ff7e47',
- 装渣: '#ff64d3',
- 运渣: '#3cecda',
- 拱架安装: '#ffc941',
- 锚杆安装: '#956dff',
- 湿喷混凝土: '#ffeb81',
- 超前支护: '#20c8ff',
- 仰拱作业: '#d510ff',
- 防排水: '#0000FF',
- 二衬作业: '#0000CD',
- 养护: '#B0C4DE',
- 水电槽: '#B0E0E6'
- }
- const time = new Array(25).fill(null).map((_, i) => i + 1)
- const planDetail = ref([] as Item[])
- const tipData = ref({
- X: -100000, name: '', st: '', et: '', Y: -10000
- } as Item)
- function countTime(item: Item[]) {
- const arr = item.map((el, k) => ({
- ...el,
- st: `${format(el.sTime, 'HH:mm')}`,
- et: `${format(el.eTime, 'HH:mm')}`,
- width: Math.floor((el.eTime! - el.sTime!) / 1000 / 60 / 60 * 10) / 10 * 60,
- X: (new Date(el.sTime!).getHours() - 1 + new Date(el.sTime!).getMinutes() / 60) * 60,
- Y: 50 + k * 40
- }))
- return arr
- }
- function details(item: Item) {
- tipData.value = {
- ...item,
- X: item.X! + item.width! / 2 - (130 / 2),
- Y: item.Y! + 20
- }
- }
- watch(() => props.data, (v) => {
- planDetail.value = countTime(v)
- }, { immediate: true })
- onMounted(() => { document.title = 'SVG进度' })
- </script>
- <style lang="scss" scoped>
- .process {
- width: 100%;
- height: 100%;
- padding: 15px;
- box-sizing: border-box;
- background: #0c1f3a;
- svg {
- user-select: none;
- }
- }
- </style>
|