第三个模块时间轴自动推进展示每个时间切片的关系图
This commit is contained in:
parent
6230c865e3
commit
c9e63e815c
BIN
src/assets/images/head/hiddenTitle.png
Normal file
BIN
src/assets/images/head/hiddenTitle.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 169 KiB |
BIN
src/assets/images/head/linkedPredictionStruct.png
Normal file
BIN
src/assets/images/head/linkedPredictionStruct.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 164 KiB |
|
|
@ -11,7 +11,7 @@
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="time-section"
|
class="time-section"
|
||||||
:style="{ left: getTimeSectionLeft(time) + 'px' }"
|
:style="{ left: nowSize(getTimeSectionLeft(time)) + 'px' }"
|
||||||
@pointerdown.stop="handleSectionPointerDown(time)"
|
@pointerdown.stop="handleSectionPointerDown(time)"
|
||||||
></div>
|
></div>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
@ -33,7 +33,7 @@
|
||||||
<div
|
<div
|
||||||
class="timeLine-point"
|
class="timeLine-point"
|
||||||
@pointerdown.stop="handlePointPointerDown"
|
@pointerdown.stop="handlePointPointerDown"
|
||||||
:style="{ left: `${currentPosition - 9}px` }"
|
:style="{ left: `${nowSize(currentPosition - 9)}px` }"
|
||||||
></div>
|
></div>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -53,12 +53,12 @@ const props = defineProps({
|
||||||
},
|
},
|
||||||
startTime: {
|
startTime: {
|
||||||
//起始时间
|
//起始时间
|
||||||
type: Date,
|
|
||||||
default: new Date("2024-05-16 16:56:04")
|
default: new Date("2024-05-16 16:56:04")
|
||||||
},
|
},
|
||||||
endTime: {
|
endTime: {
|
||||||
//结束时间
|
//结束时间
|
||||||
type: Date,
|
|
||||||
default: new Date("2024-05-23 10:16:56")
|
default: new Date("2024-05-23 10:16:56")
|
||||||
},
|
},
|
||||||
initPosition: {
|
initPosition: {
|
||||||
|
|
@ -81,7 +81,7 @@ const props = defineProps({
|
||||||
const startTime = ref(props.startTime) //开始时间
|
const startTime = ref(props.startTime) //开始时间
|
||||||
const endTime = ref(props.endTime) //结束时间
|
const endTime = ref(props.endTime) //结束时间
|
||||||
const timeList = ref(props.timeList) //时间列表
|
const timeList = ref(props.timeList) //时间列表
|
||||||
const currentTime = ref(new Date("2024-05-16 16:56:04")) // 当前选中的时间
|
const currentTime = ref(props.startTime) // 当前选中的时间
|
||||||
const currentPosition = ref(props.initPosition) // 初始位置
|
const currentPosition = ref(props.initPosition) // 初始位置
|
||||||
const isPlaying = ref(props.isAutoPlay) // 是否自动播放
|
const isPlaying = ref(props.isAutoPlay) // 是否自动播放
|
||||||
const axisRef = ref(null) // 轴的引用
|
const axisRef = ref(null) // 轴的引用
|
||||||
|
|
@ -90,7 +90,7 @@ const axisWidth = nowSize(415) // 轴的长度(px)
|
||||||
const startTimeMs = startTime.value.getTime() // 起始时间的毫秒数
|
const startTimeMs = startTime.value.getTime() // 起始时间的毫秒数
|
||||||
const endTimeMs = endTime.value.getTime() // 结束时间的毫秒数
|
const endTimeMs = endTime.value.getTime() // 结束时间的毫秒数
|
||||||
const totalDuration = endTimeMs - startTimeMs // 计算总持续时间
|
const totalDuration = endTimeMs - startTimeMs // 计算总持续时间
|
||||||
const step = 4 // 每次移动的像素数(px)
|
const step = nowSize(4) // 每次移动的像素数(px)
|
||||||
let playTimer = null // 自动播放定时器
|
let playTimer = null // 自动播放定时器
|
||||||
|
|
||||||
const emit = defineEmits(["click:pointerDown", "slide:pointerUp"])
|
const emit = defineEmits(["click:pointerDown", "slide:pointerUp"])
|
||||||
|
|
@ -138,7 +138,7 @@ watch(
|
||||||
// 让 active-needle 标定在 timeList 最后一个时间点
|
// 让 active-needle 标定在 timeList 最后一个时间点
|
||||||
const showHidden = computed(() => {
|
const showHidden = computed(() => {
|
||||||
if (!timeList.value || timeList.value.length === 0) return {}
|
if (!timeList.value || timeList.value.length === 0) return {}
|
||||||
const left = getTimeSectionLeft.value(timeList.value[timeList.value.length - 1]) + 5 // +5px 保持和 time-section 对齐
|
const left = getTimeSectionLeft.value(timeList.value[timeList.value.length - 1]) + nowSize(5) // +5px 保持和 time-section 对齐
|
||||||
return { left: `${left}px` }
|
return { left: `${left}px` }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -153,17 +153,41 @@ const pause = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 自动播放控制
|
// 自动播放控制
|
||||||
|
// 已处理过的时间点索引
|
||||||
|
let processedIndices = new Set()
|
||||||
|
|
||||||
|
// 重置已处理时间点
|
||||||
|
const resetProcessedIndices = () => {
|
||||||
|
processedIndices.clear()
|
||||||
|
}
|
||||||
|
|
||||||
const play = () => {
|
const play = () => {
|
||||||
if (!isPlaying.value) return
|
if (!isPlaying.value || timeList.value.length === 0) return
|
||||||
|
// 重置已处理索引,确保每次播放都从当前位置重新开始处理
|
||||||
playTimer = setInterval(() => {
|
playTimer = setInterval(() => {
|
||||||
if (currentPosition.value >= axisWidth) {
|
// 持续移动进度条
|
||||||
pause()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
currentPosition.value = Math.min(axisWidth, currentPosition.value + step)
|
currentPosition.value = Math.min(axisWidth, currentPosition.value + step)
|
||||||
currentTime.value = getTimeFromPosition(currentPosition.value)
|
currentTime.value = getTimeFromPosition(currentPosition.value)
|
||||||
emit("slide:pointerUp", currentTime.value)
|
// 检查当前位置是否到达或超过某个时间切片
|
||||||
}, 300) // 每300ms移动一次
|
for (let i = 0; i < timeList.value.length; i++) {
|
||||||
|
if (processedIndices.has(i)) continue
|
||||||
|
const time = timeList.value[i]
|
||||||
|
const left = getTimeSectionLeft.value(time)
|
||||||
|
// 如果当前位置超过了这个时间切片的位置,并且还没有处理过
|
||||||
|
if (
|
||||||
|
currentPosition.value >= left - nowSize(2) &&
|
||||||
|
currentPosition.value <= left + nowSize(2)
|
||||||
|
) {
|
||||||
|
currentTime.value = time // 使用精确的时间值
|
||||||
|
emit("slide:pointerUp", time) // 只在timeList中的时间点发送请求
|
||||||
|
processedIndices.add(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 如果到达终点,停止播放
|
||||||
|
if (currentPosition.value >= axisWidth) {
|
||||||
|
pause()
|
||||||
|
}
|
||||||
|
}, 500) // 每500ms移动一小步
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据位置计算时间
|
// 根据位置计算时间
|
||||||
|
|
@ -177,6 +201,7 @@ const getTimeFromPosition = (position) => {
|
||||||
const handlePointerDown = (e) => {
|
const handlePointerDown = (e) => {
|
||||||
if (e.target.classList.contains("timeLine-point")) return
|
if (e.target.classList.contains("timeLine-point")) return
|
||||||
pause() // 拖动或点击时暂停自动播放
|
pause() // 拖动或点击时暂停自动播放
|
||||||
|
resetProcessedIndices() // 重置已处理时间点
|
||||||
const rect = axisRef.value.getBoundingClientRect()
|
const rect = axisRef.value.getBoundingClientRect()
|
||||||
const position = Math.max(0, Math.min(axisWidth, e.clientX - rect.left))
|
const position = Math.max(0, Math.min(axisWidth, e.clientX - rect.left))
|
||||||
currentPosition.value = position
|
currentPosition.value = position
|
||||||
|
|
@ -189,6 +214,7 @@ const handlePointPointerDown = (e) => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
isDragging.value = true
|
isDragging.value = true
|
||||||
|
resetProcessedIndices() // 重置已处理时间点
|
||||||
// 缓存轴的边界矩形,避免重复计算
|
// 缓存轴的边界矩形,避免重复计算
|
||||||
const rect = axisRef.value.getBoundingClientRect()
|
const rect = axisRef.value.getBoundingClientRect()
|
||||||
const axisLeft = rect.left
|
const axisLeft = rect.left
|
||||||
|
|
@ -216,9 +242,10 @@ const handlePointPointerDown = (e) => {
|
||||||
document.addEventListener("pointerup", handlePointerUp)
|
document.addEventListener("pointerup", handlePointerUp)
|
||||||
}
|
}
|
||||||
|
|
||||||
const timeSectionWidth = 4 // 与样式保持一致
|
const timeSectionWidth = nowSize(4) // 与样式保持一致
|
||||||
const handleSectionPointerDown = (time) => {
|
const handleSectionPointerDown = (time) => {
|
||||||
pause()
|
pause()
|
||||||
|
resetProcessedIndices() // 重置已处理时间点
|
||||||
// 计算该时间点的中心位置
|
// 计算该时间点的中心位置
|
||||||
const left = getTimeSectionLeft.value(time) + timeSectionWidth / 2
|
const left = getTimeSectionLeft.value(time) + timeSectionWidth / 2
|
||||||
currentPosition.value = left
|
currentPosition.value = left
|
||||||
|
|
@ -232,6 +259,7 @@ const reset = () => {
|
||||||
currentTime.value = getTimeFromPosition(props.initPosition)
|
currentTime.value = getTimeFromPosition(props.initPosition)
|
||||||
// 清理旧定时器
|
// 清理旧定时器
|
||||||
pause()
|
pause()
|
||||||
|
resetProcessedIndices() // 重置已处理时间点
|
||||||
// 重新开始播放
|
// 重新开始播放
|
||||||
if (props.isAutoPlay) {
|
if (props.isAutoPlay) {
|
||||||
isPlaying.value = true
|
isPlaying.value = true
|
||||||
|
|
|
||||||
|
|
@ -186,8 +186,6 @@ export const useGroupDiscoveryStore = defineStore("groupDiscovery", {
|
||||||
//获取群体列表数据
|
//获取群体列表数据
|
||||||
async initializeGroupList(time = "") {
|
async initializeGroupList(time = "") {
|
||||||
const res = await getGroupEvolutionGroupList(time)
|
const res = await getGroupEvolutionGroupList(time)
|
||||||
console.log("群体列表:", res)
|
|
||||||
|
|
||||||
if (res.code != 200) return
|
if (res.code != 200) return
|
||||||
const iconMap = {
|
const iconMap = {
|
||||||
节点数: nodePrefix,
|
节点数: nodePrefix,
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, toRaw, watch } from "vue"
|
import { onMounted, ref, toRaw, watch } from "vue"
|
||||||
import { storeToRefs } from "pinia"
|
import { storeToRefs } from "pinia"
|
||||||
import { convertToUtcIsoString } from "@/utils/transform"
|
import { convertToUtcIsoString } from "@/utils/transform"
|
||||||
import { paintNodeFunction, paintLineFunction } from "@/utils/customePaint"
|
import { paintNodeFunction, paintLineFunction } from "@/utils/customePaint"
|
||||||
|
|
@ -59,6 +59,12 @@ const legendsMap = {
|
||||||
{ icon: abnormalLeg, text: "异常社团" }
|
{ icon: abnormalLeg, text: "异常社团" }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
const zoomSize = new Map([
|
||||||
|
["groupDiscovery", 0.15],
|
||||||
|
["groupStructure", 0.15],
|
||||||
|
["groupMember", 0.15],
|
||||||
|
["anomalousGroup", 0.7]
|
||||||
|
])
|
||||||
const emit = defineEmits(["click:pointerDownAndSlide"])
|
const emit = defineEmits(["click:pointerDownAndSlide"])
|
||||||
const { timeList, graph } = storeToRefs(props.store)
|
const { timeList, graph } = storeToRefs(props.store)
|
||||||
const graphTitle = props.store.graphTitle
|
const graphTitle = props.store.graphTitle
|
||||||
|
|
@ -166,11 +172,8 @@ const registEvents = () => {
|
||||||
const highLightAboutNodesOrLinks = (type) => {
|
const highLightAboutNodesOrLinks = (type) => {
|
||||||
graphVis.cancelAllSelected()
|
graphVis.cancelAllSelected()
|
||||||
const { newNodes, newLinks } = graph.value
|
const { newNodes, newLinks } = graph.value
|
||||||
console.log(graphVis.nodes)
|
|
||||||
console.log("进来highLightAboutNodesOrLinks")
|
|
||||||
if (type == "nodes") {
|
if (type == "nodes") {
|
||||||
//实现高亮节点逻辑
|
//实现高亮节点逻辑
|
||||||
console.log("进来if")
|
|
||||||
graphVis.nodes.forEach((node) =>
|
graphVis.nodes.forEach((node) =>
|
||||||
newNodes.forEach((newNode) => {
|
newNodes.forEach((newNode) => {
|
||||||
if (node.id === newNode.name) {
|
if (node.id === newNode.name) {
|
||||||
|
|
@ -195,63 +198,42 @@ const runDiffForceLayout = (layoutConfig, layoutType, isAsync) => {
|
||||||
function handleLayoutSuccess() {
|
function handleLayoutSuccess() {
|
||||||
//处理四个关系图的差异函数
|
//处理四个关系图的差异函数
|
||||||
const handleGroupDiscoveryDiff = () => {
|
const handleGroupDiscoveryDiff = () => {
|
||||||
console.log("进来handleGroupDiscoveryDiff")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleGroupStructureDiff = () => {
|
const handleGroupStructureDiff = () => {
|
||||||
console.log("进来handleGroupStructureDiff")
|
|
||||||
highLightAboutNodesOrLinks("links")
|
highLightAboutNodesOrLinks("links")
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleGroupMemberDiff = () => {
|
const handleGroupMemberDiff = () => {
|
||||||
console.log("进来handleGroupMemberDiff")
|
|
||||||
highLightAboutNodesOrLinks("nodes")
|
highLightAboutNodesOrLinks("nodes")
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleAnomalousGroup = () => {
|
const handleAnomalousGroup = () => {
|
||||||
// 当前时间从 store 取;没有就用 T0
|
// 当前时间从 store 取
|
||||||
const now = props.store.currentUtc
|
const now = props.store.currentUtc
|
||||||
const TA = "2024-06-19T08:57:55Z" // A
|
const abnormalData = props.store.graphAbnormalData
|
||||||
const TB = "2024-06-19T10:58:03Z" // B
|
const abnormalGroupConfigs = [
|
||||||
const TC = "2024-06-19T12:58:04Z" // C
|
{ timeThreshold: "2024-06-19T08:57:55Z", groupKey: "groupA", color: "85, 125, 15" }, // 绿色
|
||||||
// 组色(与你现有 colorMap 一致)
|
{ timeThreshold: "2024-06-19T10:58:03Z", groupKey: "groupB", color: "125, 114, 15" }, // 黄色
|
||||||
const GROUP_ALPHA = 0.3
|
{ timeThreshold: "2024-06-19T12:58:04Z", groupKey: "groupC", color: "15, 106, 125" } // 蓝色
|
||||||
const RED = "220,50,60"
|
]
|
||||||
const greenRed = "85, 125, 15"
|
// 计算当前应激活的异常组配置
|
||||||
const blueRed = "15, 106, 125"
|
const activeConfigs = abnormalGroupConfigs.filter((config) => now >= config.timeThreshold)
|
||||||
const yellowRed = "125, 114, 15"
|
// 单次遍历处理所有异常节点,避免多次map操作
|
||||||
|
graphVis.nodes = graphVis.nodes.map((node) => {
|
||||||
// 时间门控:达到阈值就把各组异常节点染红
|
// 检查节点是否属于任何激活的异常组
|
||||||
const shouldA = now >= TA
|
for (const config of activeConfigs) {
|
||||||
const shouldB = now >= TB
|
const abnormalIds = abnormalData[config.groupKey]
|
||||||
const shouldC = now >= TC
|
// 如果节点在异常组中,则设置对应的颜色
|
||||||
if (shouldA) {
|
if (abnormalIds && abnormalIds.includes(node.id)) {
|
||||||
graphVis.nodes = graphVis.nodes.map((n) => {
|
node.fillColor = config.color
|
||||||
if (props.store.graphAbnormalData.groupA.includes(n.id)) {
|
break // 一旦找到匹配的异常组,就不再检查其他组
|
||||||
// n.fillColor = RED
|
|
||||||
n.fillColor = greenRed
|
|
||||||
}
|
}
|
||||||
return n
|
}
|
||||||
|
return node
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (shouldB) {
|
|
||||||
graphVis.nodes = graphVis.nodes.map((n) => {
|
|
||||||
if (props.store.graphAbnormalData.groupB.includes(n.id)) {
|
|
||||||
n.fillColor = yellowRed
|
|
||||||
}
|
|
||||||
return n
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (shouldC) {
|
|
||||||
graphVis.nodes = graphVis.nodes.map((n) => {
|
|
||||||
if (props.store.graphAbnormalData.groupC.includes(n.id)) {
|
|
||||||
n.fillColor = blueRed
|
|
||||||
}
|
|
||||||
return n
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
new Map([
|
new Map([
|
||||||
["groupDiscovery", () => handleGroupDiscoveryDiff()],
|
["groupDiscovery", () => handleGroupDiscoveryDiff()],
|
||||||
|
|
@ -259,11 +241,10 @@ const runDiffForceLayout = (layoutConfig, layoutType, isAsync) => {
|
||||||
["groupMember", () => handleGroupMemberDiff()],
|
["groupMember", () => handleGroupMemberDiff()],
|
||||||
["anomalousGroup", () => handleAnomalousGroup()]
|
["anomalousGroup", () => handleAnomalousGroup()]
|
||||||
]).get(storeId)?.()
|
]).get(storeId)?.()
|
||||||
// isPlay.value = true
|
isPlay.value = true
|
||||||
graphVis.zoomFit() //场景视图大小自适应缩放
|
graphVis.moveCenter(zoomSize.get(storeId)) //组件布局完毕后自动让整体关系图大小缩放到指定比例
|
||||||
}
|
}
|
||||||
graphVis.excuteLocalLayout(layoutType, layoutConfig, isAsync, () => handleLayoutSuccess())
|
graphVis.excuteLocalLayout(layoutType, layoutConfig, isAsync, handleLayoutSuccess())
|
||||||
// graphVis.autoGroupLayout(graphVis.getGraphData())
|
|
||||||
}
|
}
|
||||||
// 根据节点的cluster属性进行分组
|
// 根据节点的cluster属性进行分组
|
||||||
const clusterAnalyze = () => {
|
const clusterAnalyze = () => {
|
||||||
|
|
@ -324,7 +305,7 @@ const createGraph = () => {
|
||||||
}
|
}
|
||||||
graphVis.setDragHideLine(false) //拖拽时隐藏连线
|
graphVis.setDragHideLine(false) //拖拽时隐藏连线
|
||||||
graphVis.setShowDetailScale(0.1) //展示细节的比例
|
graphVis.setShowDetailScale(0.1) //展示细节的比例
|
||||||
graphVis.setZoomRange(0.1, 5) //缩放区间
|
graphVis.setZoomRange(0.1, 10) //缩放区间
|
||||||
registCustomePaintFunc(storeId) //注册自定义绘图方法
|
registCustomePaintFunc(storeId) //注册自定义绘图方法
|
||||||
registEvents()
|
registEvents()
|
||||||
}
|
}
|
||||||
|
|
@ -333,9 +314,21 @@ const initChart = () => {
|
||||||
createGraph()
|
createGraph()
|
||||||
graphVis.addGraph({ ...toRaw(graph.value) })
|
graphVis.addGraph({ ...toRaw(graph.value) })
|
||||||
clusterAnalyze()
|
clusterAnalyze()
|
||||||
runDiffForceLayout({ strength: -500, ajustCluster: true }, "simulation", true)
|
runDiffForceLayout({ strength: -300, ajustCluster: true }, "simulation", false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 初始化时,如果有时间列表且当前没有图表数据,请求第一个时间切片的数据
|
||||||
|
if (
|
||||||
|
timeList.value.length > 0 &&
|
||||||
|
(!graph.value || !graph.value.nodes || graph.value.nodes.length === 0)
|
||||||
|
) {
|
||||||
|
const firstTime = timeList.value[0]
|
||||||
|
const utcTime = convertToUtcIsoString(firstTime)
|
||||||
|
emit("click:pointerDownAndSlide", utcTime)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// 添加更新图表的函数
|
// 添加更新图表的函数
|
||||||
const updateChart = (newGraphData) => {
|
const updateChart = (newGraphData) => {
|
||||||
if (!graphVis) {
|
if (!graphVis) {
|
||||||
|
|
@ -346,7 +339,7 @@ const updateChart = (newGraphData) => {
|
||||||
graphVis.addGraph({ ...toRaw(newGraphData) })
|
graphVis.addGraph({ ...toRaw(newGraphData) })
|
||||||
// 重新运行力导向布局
|
// 重新运行力导向布局
|
||||||
clusterAnalyze()
|
clusterAnalyze()
|
||||||
runDiffForceLayout({ strength: -500, ajustCluster: true }, "simulation", true)
|
runDiffForceLayout({ strength: -300, ajustCluster: true }, "simulation", false)
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
|
|
|
||||||
|
|
@ -301,7 +301,7 @@ provide("statisticsList", characterHiddenStore.statisticsList)
|
||||||
.top-container {
|
.top-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: vh(110);
|
height: vh(110);
|
||||||
background-image: url(@/assets/images/linkPrediction/title/page-title.png);
|
background-image: url("@/assets/images/head/hiddenTitle.png");
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
fill: linear-gradient(270deg, rgba(6, 61, 113, 0.1) 0%, rgba(8, 30, 56, 0.38) 100%);
|
fill: linear-gradient(270deg, rgba(6, 61, 113, 0.1) 0%, rgba(8, 30, 56, 0.38) 100%);
|
||||||
|
|
|
||||||
|
|
@ -332,7 +332,7 @@ provide("statisticsList", socialGroupsStore.statisticsList)
|
||||||
.top-container {
|
.top-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: vh(110);
|
height: vh(110);
|
||||||
background-image: url(@/assets/images/linkPrediction/title/page-title.png);
|
background-image: url("@/assets/images/head/linkedPredictionStruct.png");
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
fill: linear-gradient(270deg, rgba(6, 61, 113, 0.1) 0%, rgba(8, 30, 56, 0.38) 100%);
|
fill: linear-gradient(270deg, rgba(6, 61, 113, 0.1) 0%, rgba(8, 30, 56, 0.38) 100%);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user