feat: 按指定格式渲染nodes和links数据
This commit is contained in:
parent
a1382b84ca
commit
027a4166c5
1433
src/data/graphData.ts
Normal file
1433
src/data/graphData.ts
Normal file
File diff suppressed because it is too large
Load Diff
629
src/views/index.vue
Normal file
629
src/views/index.vue
Normal file
|
|
@ -0,0 +1,629 @@
|
||||||
|
<template>
|
||||||
|
<div class="sky-page-box sky-pageBgc-r" ref="pageBoxRef" id="visualize_2d">
|
||||||
|
<!-- 时间轴 -->
|
||||||
|
<div class="sky-time-box sky-flex-rsc">
|
||||||
|
<div>{{ dateFormat(temporalTimeMin, 'YYYY/MM/DD') }}</div>
|
||||||
|
<div class="sky-position-r sky-w-50 sky-ml-10 sky-mr-15 sky-mt-2 sky-w-500px h-5px">
|
||||||
|
<!-- 此处更换时间轴图标 -->
|
||||||
|
<img v-for="(item, index) in init_time_left" :key="index" src="./assets/img/initNode_time.svg?url"
|
||||||
|
style="position: absolute; left: 0%; transform: translate(-50%, -30%); z-index: 10"
|
||||||
|
:style="{ left: item }" alt="" />
|
||||||
|
<img v-for="(item, index) in importantNode_time_left" :key="index"
|
||||||
|
src="./assets/img/importantNode_time.svg?url"
|
||||||
|
style="position: absolute; transform: translate(-40%, -30%); z-index: 10" :style="{ left: item }"
|
||||||
|
alt="" />
|
||||||
|
<t-slider :min="temporalTimeMin" :max="temporalTimeMax" :show-tooltip="true" class="sky-timeSlider"
|
||||||
|
v-model="temporalTime" :label="handleTimeLabel" @change-end="changeTemporalTimeEnd">
|
||||||
|
<template #Lable="{ value }">
|
||||||
|
<span>当前值: {{ value * 2 }}</span>
|
||||||
|
</template>
|
||||||
|
<template #button>
|
||||||
|
<img src="./user/lao.png"
|
||||||
|
style="position: absolute; transform: translate(-50%, -100%)"
|
||||||
|
:style="{ left: temporalTick }" alt="" />
|
||||||
|
</template>
|
||||||
|
</t-slider>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>{{ dateFormat(temporalTimeMax, 'YYYY/MM/DD') }}</div>
|
||||||
|
|
||||||
|
<PlayCircleIcon v-if="temporalPlayShow" class="sky-fs-20 sky-hover-c-primary sky-ml-10"
|
||||||
|
@click="handleTemporaPlay" />
|
||||||
|
<PauseCircleIcon v-else class="sky-fs-20 sky-hover-c-primary sky-ml-10" @click="handleTemporaPause" />
|
||||||
|
</div>
|
||||||
|
<!--图显示区域-->
|
||||||
|
<div class="sky-graph-area sky-flex-rss sky-graph-area-h1">
|
||||||
|
<!-- 绘图面板区域 -->
|
||||||
|
<div ref="graphPanelRef" id="sky-graph-panel" style="width: 100%; height: calc(100% - 2px)"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<t-loading v-if="isLayouting" class="sky-layoutLoading" text="正在布局..." size="small"></t-loading>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="tsx">
|
||||||
|
export default {
|
||||||
|
name: '',
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="tsx" setup>
|
||||||
|
import { onMounted, reactive, ref, nextTick, toRaw, onBeforeUnmount, Ref } from 'vue'
|
||||||
|
|
||||||
|
import { PlayCircleIcon, PauseCircleIcon } from 'tdesign-icons-vue-next'
|
||||||
|
|
||||||
|
import GraphVis from '../assets/graphvis/graphvis.esm.min3.js'
|
||||||
|
import { getDefaultConfig } from '../assets/graphvis/defaultConfig.js'
|
||||||
|
import { getLayoutDefaultConfig } from '../assets/graphvis/layoutParamsDict.js'
|
||||||
|
|
||||||
|
import { MessagePlugin } from 'tdesign-vue-next'
|
||||||
|
import timeData from '../data/graphData'
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
import { id } from 'element-plus/es/locales.mjs'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
graphData: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {
|
||||||
|
nodes: [
|
||||||
|
{
|
||||||
|
id: '人民网',
|
||||||
|
type: 'user',
|
||||||
|
properties: { name: 'Lionel Roob', special_type: ['initial'], },
|
||||||
|
personProperties: {url:('src/views/user/boss.png')},
|
||||||
|
}
|
||||||
|
|
||||||
|
],
|
||||||
|
links: [
|
||||||
|
|
||||||
|
],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
duSize: {
|
||||||
|
// 根据度 改变 node size
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const dateFormat = (date, format = 'YYYY-MM-DD HH:mm:ss') => {
|
||||||
|
if (!date) return '暂无'
|
||||||
|
return dayjs(date).format(format)
|
||||||
|
}
|
||||||
|
let LicenseKey =
|
||||||
|
'01D01J01E01A01D01I01A01E01C01A01D00Z03003903303402P03202N03702R02X02R03303103402P037037'
|
||||||
|
|
||||||
|
const isLayouting = ref(false)
|
||||||
|
let visualizeData = reactive({
|
||||||
|
nodes: [],
|
||||||
|
links: [],
|
||||||
|
})
|
||||||
|
|
||||||
|
const initVisualizeData = () => {
|
||||||
|
const { nodes, links } = props.graphData
|
||||||
|
|
||||||
|
if (Array.isArray(links) && Array.isArray(nodes) && (links.length || nodes.length)) {
|
||||||
|
visualizeData = {
|
||||||
|
links: initLinkStyle(links, nodes),
|
||||||
|
nodes: initNodeStyle(nodes, links),
|
||||||
|
}
|
||||||
|
if (!validate) {
|
||||||
|
MessagePlugin.warning('暂不支持进入时序动态网络')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
createGraph() //初始化客户端
|
||||||
|
nextTick(() => {
|
||||||
|
initGraphData() //初始化加载数据并绘图
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
MessagePlugin.error('数据有误')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建全局绘图客户端对象
|
||||||
|
let graphVis: any = null
|
||||||
|
let graphPanelRef = ref(null)
|
||||||
|
const createGraph = () => {
|
||||||
|
graphVis = new GraphVis({
|
||||||
|
container: document.getElementById('sky-graph-panel'),
|
||||||
|
licenseKey: LicenseKey,
|
||||||
|
config: getDefaultConfig(),
|
||||||
|
})
|
||||||
|
graphVis.setDragHideLine(false) //拖拽时隐藏连线
|
||||||
|
graphVis.setShowDetailScale(0.1) //展示细节的比例
|
||||||
|
graphVis.setZoomRange(0.1, 5) //缩放区间
|
||||||
|
}
|
||||||
|
// 初始化图谱数据
|
||||||
|
|
||||||
|
const initGraphData = () => {
|
||||||
|
graphVis.addGraph(visualizeData)
|
||||||
|
nextTick(() => {
|
||||||
|
layoutEvent('fastForce')
|
||||||
|
graphVis.zoomFit()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 节点大小
|
||||||
|
|
||||||
|
const setNodeSize = (nodelist = []) => {
|
||||||
|
let leg = nodelist.length
|
||||||
|
let size = 10
|
||||||
|
if (leg <= 10) {
|
||||||
|
size = 26
|
||||||
|
} else if (leg <= 30) {
|
||||||
|
size = 24
|
||||||
|
} else if (leg <= 50) {
|
||||||
|
size = 22
|
||||||
|
} else if (leg <= 100) {
|
||||||
|
size = 20
|
||||||
|
} else if (leg <= 500) {
|
||||||
|
size = 18
|
||||||
|
} else if (leg <= 1000) {
|
||||||
|
size = 16
|
||||||
|
} else if (leg <= 5000) {
|
||||||
|
size = 14
|
||||||
|
} else if (leg <= 10000) {
|
||||||
|
size = 12
|
||||||
|
} else {
|
||||||
|
size = 10
|
||||||
|
}
|
||||||
|
|
||||||
|
return size
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化 节点样式
|
||||||
|
const initNodeStyle = (nodeList = [], linkList = [], doAlgStyle = false) => {
|
||||||
|
let nodeIdCount = {}
|
||||||
|
let nodeIdsAll = []
|
||||||
|
let resNodes = []
|
||||||
|
|
||||||
|
linkList.forEach((link) => {
|
||||||
|
let source = link.source
|
||||||
|
if (source) {
|
||||||
|
if (nodeIdCount[source]) {
|
||||||
|
nodeIdCount[source]++
|
||||||
|
} else {
|
||||||
|
nodeIdsAll.push(source)
|
||||||
|
nodeIdCount[source] = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let target = link.target
|
||||||
|
if (target) {
|
||||||
|
if (nodeIdCount[target]) {
|
||||||
|
nodeIdCount[target]++
|
||||||
|
} else {
|
||||||
|
nodeIdsAll.push(target)
|
||||||
|
nodeIdCount[target] = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let descCountArr = Array.from(new Set(Object.values(nodeIdCount).sort()))
|
||||||
|
let ratio = descCountArr.length > 10 ? 10 : descCountArr.length
|
||||||
|
let maxVal = Math.max(...descCountArr)
|
||||||
|
let minVal = Math.min(...descCountArr)
|
||||||
|
|
||||||
|
let size = setNodeSize(nodeList)
|
||||||
|
let isolateNum = 0
|
||||||
|
let nodeObj = {} // 去重
|
||||||
|
let maxSize = 0
|
||||||
|
nodeList.forEach((node) => {
|
||||||
|
if (!node.style) {
|
||||||
|
node.style = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理节点标签
|
||||||
|
let propName = node.properties?.name || node.properties?.author_name || ''
|
||||||
|
if (propName) {
|
||||||
|
node.label = propName
|
||||||
|
}
|
||||||
|
if (!node.color) {
|
||||||
|
node.color = '255,96,96'
|
||||||
|
}
|
||||||
|
if (!node.size) {
|
||||||
|
node.size = size
|
||||||
|
}
|
||||||
|
|
||||||
|
// 节点大小处理
|
||||||
|
if (props.duSize && nodeIdCount[node.id] && maxVal > minVal) {
|
||||||
|
let enlargeNum = ((20 + 3 * ratio) * (nodeIdCount[node.id] - minVal)) / (maxVal - minVal)
|
||||||
|
node.size = Number(node.size) + Math.ceil(enlargeNum)
|
||||||
|
}
|
||||||
|
|
||||||
|
maxSize = Math.max(maxSize, node.size)
|
||||||
|
|
||||||
|
if (!nodeObj[node.id]) {
|
||||||
|
// 去重
|
||||||
|
nodeObj[node.id] = 1
|
||||||
|
|
||||||
|
if (nodeIdsAll.includes(node.id)) {
|
||||||
|
// 不是孤立节点
|
||||||
|
|
||||||
|
resNodes.push({
|
||||||
|
...node,
|
||||||
|
})
|
||||||
|
} else if (isolateNum < 10) {
|
||||||
|
// 只显示 10个孤立点
|
||||||
|
|
||||||
|
isolateNum++
|
||||||
|
resNodes.push({
|
||||||
|
...node,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
nodeObj[node.id]++
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
handleTemporalTimeRange()
|
||||||
|
handleImportantTag(nodeList, linkList)
|
||||||
|
|
||||||
|
return resNodes
|
||||||
|
}
|
||||||
|
|
||||||
|
const setLinkWidth = (linkList = [], nodeList = []) => {
|
||||||
|
let leg = linkList.length + nodeList.length
|
||||||
|
|
||||||
|
let wd = 1
|
||||||
|
if (leg <= 10) {
|
||||||
|
wd = 3.25
|
||||||
|
} else if (leg <= 30) {
|
||||||
|
wd = 3
|
||||||
|
} else if (leg <= 50) {
|
||||||
|
wd = 2.75
|
||||||
|
} else if (leg <= 100) {
|
||||||
|
wd = 2.5
|
||||||
|
} else if (leg <= 500) {
|
||||||
|
wd = 2.25
|
||||||
|
} else if (leg <= 1000) {
|
||||||
|
wd = 2
|
||||||
|
} else if (leg <= 2000) {
|
||||||
|
wd = 1.75
|
||||||
|
} else if (leg <= 5000) {
|
||||||
|
wd = 1.5
|
||||||
|
} else if (leg <= 10000) {
|
||||||
|
wd = 1.25
|
||||||
|
} else {
|
||||||
|
wd = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return wd
|
||||||
|
}
|
||||||
|
// 校验可视化数据
|
||||||
|
let validate = false
|
||||||
|
// 初始化 连边样式
|
||||||
|
const initLinkStyle = (links = [], nodes = []) => {
|
||||||
|
let wd = setLinkWidth(links, nodes)
|
||||||
|
let resLinks = []
|
||||||
|
links.forEach((link) => {
|
||||||
|
if (!link.lineWidth) {
|
||||||
|
link.lineWidth = wd
|
||||||
|
}
|
||||||
|
if (link.enlarge) {
|
||||||
|
const enlarge = Number(link.enlarge) || 1.5
|
||||||
|
link.lineWidth = Number(link.lineWidth) * enlarge
|
||||||
|
}
|
||||||
|
if (link.ranks) {
|
||||||
|
validate = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 时序 时间范围
|
||||||
|
|
||||||
|
if (!link.properties) {
|
||||||
|
link.properties = {}
|
||||||
|
}
|
||||||
|
if (!link.ranks) {
|
||||||
|
link.ranks = []
|
||||||
|
}
|
||||||
|
if (link.ranks) {
|
||||||
|
link.properties.ranks = link.ranks
|
||||||
|
temporalTimeRange.push(...link.properties.ranks)
|
||||||
|
}
|
||||||
|
resLinks.push({
|
||||||
|
...link,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return resLinks
|
||||||
|
}
|
||||||
|
|
||||||
|
//当前布局信息
|
||||||
|
let currentLayout = ref({
|
||||||
|
preLayout: 'fastForce',
|
||||||
|
type: '',
|
||||||
|
icon: 'el-icon-video-play',
|
||||||
|
text: '执行布局',
|
||||||
|
status: false,
|
||||||
|
layoutConfigText: '布局参数设置',
|
||||||
|
})
|
||||||
|
const layoutEvent = (layoutType, params = {}) => {
|
||||||
|
// console.log(12)
|
||||||
|
|
||||||
|
// if (stopOperation(true,false)) return;
|
||||||
|
currentLayout.value.type = layoutType
|
||||||
|
runLayout(params)
|
||||||
|
}
|
||||||
|
const runLayout = (params) => {
|
||||||
|
if (currentLayout.value.status) {
|
||||||
|
graphVis.stopLayout()
|
||||||
|
endLayoutCallback()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let layoutType = currentLayout.value.type
|
||||||
|
currentLayout.value.icon = 'el-icon-loading' //运行中
|
||||||
|
currentLayout.value.text = '布局中,点击停止'
|
||||||
|
currentLayout.value.status = true
|
||||||
|
currentLayout.value.layoutConfigText = '布局中,点击停止'
|
||||||
|
let graphData = graphVis.getVisibleData() //可视化数据
|
||||||
|
|
||||||
|
let layoutConfig = getLayoutDefaultConfig(layoutType, params)
|
||||||
|
|
||||||
|
graphVis.excuteWorkerLayout(graphData, layoutType, layoutConfig, false, function () {
|
||||||
|
endLayoutCallback()
|
||||||
|
MessagePlugin.success('布局成功')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const endLayoutCallback = () => {
|
||||||
|
//布局结束的处理
|
||||||
|
currentLayout.value.icon = 'el-icon-video-play'
|
||||||
|
currentLayout.value.text = '开始布局'
|
||||||
|
currentLayout.value.status = false
|
||||||
|
currentLayout.value.preLayout = currentLayout.value.type
|
||||||
|
currentLayout.value.layoutConfigText = '布局参数设置'
|
||||||
|
graphVis.moveCenter && graphVis.moveCenter()
|
||||||
|
toolBarEvent('zoom', 'auto')
|
||||||
|
}
|
||||||
|
const toolBarEvent = (eventType, type) => {
|
||||||
|
if (eventType == 'zoom') {
|
||||||
|
graphVis.setZoom(type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 时序网络
|
||||||
|
let temporalTime = ref(0)
|
||||||
|
let temporalTimeMin = ref(0)
|
||||||
|
let temporalTimeMax = ref(0)
|
||||||
|
let temporalTimeRange = []
|
||||||
|
let temporalPlayShow = ref(true)
|
||||||
|
let temporaInterval = null
|
||||||
|
let temporalTick = ref('0%')
|
||||||
|
// 重要节点和首发节点的坐标 left
|
||||||
|
let importantNode_time_left = ref([])
|
||||||
|
let init_time_left = ref([])
|
||||||
|
const handleTemporalTimeRange = () => {
|
||||||
|
temporalTimeRange = temporalTimeRange.map((time) => new Date(time).getTime())
|
||||||
|
temporalTimeMin.value = Math.min(...temporalTimeRange)
|
||||||
|
temporalTimeMax.value = Math.max(...temporalTimeRange)
|
||||||
|
temporalTime.value = temporalTimeMax.value
|
||||||
|
}
|
||||||
|
|
||||||
|
const set_important_left_map = (node, map, ratio) => {
|
||||||
|
if (
|
||||||
|
!map.has(node.id) &&
|
||||||
|
(node.properties?.special_type?.includes('post_importantNode') ||
|
||||||
|
node.properties?.special_type?.includes('user_importantNode'))
|
||||||
|
) {
|
||||||
|
map.set(node.id, `${Math.round(ratio * 100)}%`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const set_init_left_map = (node, map, ratio) => {
|
||||||
|
if (!map.has(node.id) && node.properties?.special_type?.includes('initial')) {
|
||||||
|
map.set(node.id, `${Math.round(ratio * 100)}%`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleImportantTag = (nodeList, linkList) => {
|
||||||
|
const temporalTimeRange_copy = [...temporalTimeRange]
|
||||||
|
let important_left_map = new Map()
|
||||||
|
let init_left_map = new Map()
|
||||||
|
temporalTimeRange_copy.sort()
|
||||||
|
temporalTimeRange_copy.forEach((curTime) => {
|
||||||
|
const curLinks = linkList.filter((link) => {
|
||||||
|
let ranks = link.properties.ranks.map((time) => new Date(time).getTime())
|
||||||
|
if (ranks.includes(curTime)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
curLinks.forEach((link) => {
|
||||||
|
const source = nodeList.find((node) => node.id === link.source)
|
||||||
|
const target = nodeList.find((node) => node.id === link.target)
|
||||||
|
if (source && target) {
|
||||||
|
const ratio =
|
||||||
|
(curTime - temporalTimeMin.value) / (temporalTimeMax.value - temporalTimeMin.value)
|
||||||
|
// 判断节点是否是重要节点并添加到important_left_map
|
||||||
|
set_important_left_map(source, important_left_map, ratio)
|
||||||
|
set_important_left_map(target, important_left_map, ratio)
|
||||||
|
// 判断节点是否是首发节点并添加到init_left_map
|
||||||
|
set_init_left_map(source, init_left_map, ratio)
|
||||||
|
set_init_left_map(target, init_left_map, ratio)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
importantNode_time_left.value = Array.from(important_left_map.values())
|
||||||
|
init_time_left.value = Array.from(init_left_map.values())
|
||||||
|
}
|
||||||
|
const handleTimeLabel = () => {
|
||||||
|
return dateFormat(temporalTime.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const changeTemporalTimeEnd = () => {
|
||||||
|
temporalGraphRefresh(temporalTime.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const temporalGraphRefresh = (time) => {
|
||||||
|
graphVis.nodes.forEach((node) => (node.visible = false))
|
||||||
|
graphVis.links.forEach((item) => {
|
||||||
|
let ranks = item.properties.ranks.map((time) => new Date(time).getTime())
|
||||||
|
ranks.sort()
|
||||||
|
|
||||||
|
// 计算小于等于当前时间的时间点数量
|
||||||
|
const link_time = ranks.filter((t) => t <= time)
|
||||||
|
const count = link_time.length
|
||||||
|
if (count > 0) {
|
||||||
|
item.visible = true
|
||||||
|
let source = graphVis.findNodeById(item.source.id)
|
||||||
|
let target = graphVis.findNodeById(item.target.id)
|
||||||
|
source.visible = true
|
||||||
|
target.visible = true
|
||||||
|
if (count >= 2) {
|
||||||
|
item.label = count
|
||||||
|
item.showlabel = true
|
||||||
|
} else {
|
||||||
|
item.showlabel = false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
item.visible = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
graphVis.refreshView()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleTemporaPlay = () => {
|
||||||
|
let step = Math.floor((temporalTimeMax.value - temporalTimeMin.value) / 20)
|
||||||
|
// 点击播放时,如果处于最大时间,则从头开始播放
|
||||||
|
if (temporalTime.value === temporalTimeMax.value) {
|
||||||
|
temporalTime.value = temporalTimeMin.value
|
||||||
|
temporalGraphRefresh(temporalTime.value)
|
||||||
|
}
|
||||||
|
// 1小时
|
||||||
|
// let step = 60 * 60 * 1000;
|
||||||
|
temporalPlayShow.value = false
|
||||||
|
temporaInterval = setInterval(() => {
|
||||||
|
let nextTime = temporalTime.value + step
|
||||||
|
if (nextTime >= temporalTimeMax.value) {
|
||||||
|
nextTime = temporalTimeMax.value
|
||||||
|
clearInterval(temporaInterval)
|
||||||
|
temporalPlayShow.value = true
|
||||||
|
temporaInterval = null
|
||||||
|
}
|
||||||
|
temporalTime.value = nextTime
|
||||||
|
const ratio =
|
||||||
|
(temporalTime.value - temporalTimeMin.value) / (temporalTimeMax.value - temporalTimeMin.value)
|
||||||
|
temporalTick.value = `${Math.round(ratio * 100)}%`
|
||||||
|
temporalGraphRefresh(nextTime)
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleTemporaPause = () => {
|
||||||
|
clearInterval(temporaInterval)
|
||||||
|
temporalPlayShow.value = true
|
||||||
|
temporaInterval = null
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
initVisualizeData()
|
||||||
|
})
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
graphVis = null
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.sky-page-box {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
min-width: 600px;
|
||||||
|
min-height: 600px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sky-graph-area-h1 {
|
||||||
|
height: calc(100% - 80px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sky-layoutLoading {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sky-time-box {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 16px;
|
||||||
|
right: 80px;
|
||||||
|
z-index: 10;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.sky-timeSlider .t-slider__button) {
|
||||||
|
transform: translateY(-75%);
|
||||||
|
width: 18px;
|
||||||
|
height: 24px;
|
||||||
|
background-image: url('../src/assets/img/slider_curr.svg');
|
||||||
|
border: none;
|
||||||
|
box-shadow: none;
|
||||||
|
border-radius: 0%;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.sky-timeSlider .t-slider .t-slider__rail .t-slider__track) {
|
||||||
|
background-color: #bc1b22;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style lang="less">
|
||||||
|
.sky-pageBgc-r {
|
||||||
|
background: #f5f1f1 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sky-flex-rsc {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sky-flex-rss {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sky-position-r {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
each(range(100), {
|
||||||
|
.sky-w-@{value} {
|
||||||
|
width: (@value * 1%);
|
||||||
|
}
|
||||||
|
|
||||||
|
}) each(range(2000), {
|
||||||
|
.sky-w-@{value}px {
|
||||||
|
width: (@value * 1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
}) each(range(200), {
|
||||||
|
.sky-m-@{value} {
|
||||||
|
margin:(@value * 1px)
|
||||||
|
}
|
||||||
|
|
||||||
|
.sky-ml-@{value} {
|
||||||
|
margin-left:(@value * 1px)
|
||||||
|
}
|
||||||
|
|
||||||
|
.sky-mr-@{value} {
|
||||||
|
margin-right:(@value * 1px)
|
||||||
|
}
|
||||||
|
|
||||||
|
.sky-mb-@{value} {
|
||||||
|
margin-bottom:(@value * 1px)
|
||||||
|
}
|
||||||
|
|
||||||
|
.sky-mt-@{value} {
|
||||||
|
margin-top:(@value * 1px)
|
||||||
|
}
|
||||||
|
|
||||||
|
}) each(range(50), {
|
||||||
|
.sky-fs-@{value} {
|
||||||
|
font-size: (@value * 1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
}) .sky-hover-c-primary {
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--td-brand-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Loading…
Reference in New Issue
Block a user