212 lines
4.9 KiB
Vue
212 lines
4.9 KiB
Vue
<script setup lang="ts">
|
||
import * as echarts from 'echarts'
|
||
import type { EChartsOption } from 'echarts'
|
||
import { log } from 'echarts/types/src/util/log.js';
|
||
import { onMounted } from 'vue';
|
||
const a = {
|
||
id: 1,
|
||
parentId: null,
|
||
label: "root",
|
||
createTime: '2024-9-21',
|
||
children: [
|
||
{
|
||
id: 2,
|
||
parentId: 1,
|
||
label: "root2", createTime: '2024-9-21',
|
||
|
||
children: [
|
||
{
|
||
id: 20,
|
||
parentId: 12,
|
||
label: "root20", createTime: '2024-9-23',
|
||
|
||
children: null
|
||
}
|
||
]
|
||
}, {
|
||
id: 3,
|
||
parentId: 1,
|
||
label: "root3", createTime: '2024-9-27', children: [{
|
||
id: 30,
|
||
parentId: 3,
|
||
label: "root30", createTime: '2024-10-21',
|
||
children: null
|
||
}, {
|
||
id: 31,
|
||
parentId: 3,
|
||
label: "root31", createTime: '2024-10-23',
|
||
children: null
|
||
}],
|
||
}
|
||
]
|
||
}
|
||
var option: EChartsOption;
|
||
function transformToGraphData(data: any) {
|
||
const graphData: [string, number][] = []; // 存储 [日期, 值]
|
||
const links: { source: number; target: number }[] = []; // 存储连接关系
|
||
const nodeInfoMap: Record<number, any> = {}; // 存储每个节点的对象数据,key 为 nodeId
|
||
let nodeId = 0; // 用于标识每个节点的唯一索引
|
||
const nodeMap: Record<number, number> = {}; // 用于映射节点 id 到 graphData 的索引
|
||
|
||
function traverse(node: any, parentIndex: number | null) {
|
||
const currentIndex = nodeId++;
|
||
// 映射当前节点 id 到 graphData 的索引
|
||
nodeMap[node.id] = currentIndex;
|
||
|
||
// 添加当前节点的数据到 graphData
|
||
graphData.push([node.createTime, node.id]);
|
||
|
||
// 存储当前节点完整对象到 nodeInfoMap
|
||
nodeInfoMap[node.id] = { ...node };
|
||
|
||
// 如果存在父节点,创建 link
|
||
if (parentIndex !== null) {
|
||
links.push({
|
||
source: parentIndex,
|
||
target: currentIndex,
|
||
});
|
||
}
|
||
|
||
// 遍历子节点
|
||
if (node.children && Array.isArray(node.children)) {
|
||
node.children.forEach((child: any) => traverse(child, currentIndex));
|
||
}
|
||
}
|
||
|
||
// 从根节点开始递归
|
||
traverse(data, null);
|
||
|
||
return { graphData, links, nodeInfoMap };
|
||
}
|
||
const graphData1: [string, number][] = [
|
||
['2017-02-01', 260],
|
||
['2017-02-04', 200],
|
||
['2017-02-09', 279],
|
||
['2017-02-13', 847],
|
||
['2017-02-18', 241],
|
||
['2017-02-23', 411],
|
||
['2017-03-14', 985]
|
||
];
|
||
const links2 = graphData1.map(function (item, idx) {
|
||
return {
|
||
source: idx,
|
||
target: idx + 1
|
||
};
|
||
});
|
||
links2.pop();
|
||
function getVirtualData(year: string) {
|
||
const date = +echarts.time.parse(year + '-01-01');
|
||
const end = +echarts.time.parse(+year + 1 + '-01-01');
|
||
const dayTime = 3600 * 24 * 1000;
|
||
const data: [string, number][] = [];
|
||
for (let time = date; time < end; time += dayTime) {
|
||
data.push([
|
||
echarts.time.format(time, '{yyyy}-{MM}-{dd}', false),
|
||
Math.floor(Math.random() * 1000)
|
||
]);
|
||
}
|
||
return data;
|
||
}
|
||
const { graphData, links, nodeInfoMap } = transformToGraphData(a);
|
||
|
||
option = {
|
||
tooltip: {
|
||
trigger:"item",
|
||
formatter:(params)=>{
|
||
const nodeData = nodeInfoMap[params.data[1]]; // 根据 ID 获取完整对象
|
||
|
||
if (params.dataType === 'node') {
|
||
// 节点的悬浮提示内容
|
||
return `
|
||
<b>ID:</b> ${nodeData.id}<br>
|
||
<b>Label:</b> ${nodeData.label}<br>
|
||
<b>Create Time:</b> ${nodeData.createTime}
|
||
`;
|
||
}
|
||
return '';
|
||
}
|
||
},
|
||
calendar: {
|
||
top: 'middle',
|
||
left: 'center',
|
||
orient: 'horizontal',
|
||
cellSize: 40,
|
||
yearLabel: {
|
||
margin: 50,
|
||
fontSize: 30
|
||
},
|
||
dayLabel: {
|
||
firstDay: 1,
|
||
nameMap: 'cn'
|
||
},
|
||
monthLabel: {
|
||
nameMap: 'cn',
|
||
margin: 15,
|
||
fontSize: 20,
|
||
color: '#999'
|
||
},
|
||
range: ['2024-09', '2024-12-31']
|
||
},
|
||
visualMap: {
|
||
min: 0,
|
||
max: 1000,
|
||
type: 'piecewise',
|
||
left: 'center',
|
||
bottom: 20,
|
||
inRange: {
|
||
color: ['#5291FF', '#C7DBFF']
|
||
},
|
||
seriesIndex: [1],
|
||
orient: 'horizontal'
|
||
},
|
||
series: [
|
||
{
|
||
type: 'graph',
|
||
edgeSymbol: ['none', 'arrow'],
|
||
coordinateSystem: 'calendar',
|
||
links: links,
|
||
symbolSize: 15,
|
||
calendarIndex: 0,
|
||
itemStyle: {
|
||
color: 'yellow',
|
||
shadowBlur: 9,
|
||
shadowOffsetX: 1.5,
|
||
shadowOffsetY: 3,
|
||
shadowColor: '#555'
|
||
},
|
||
lineStyle: {
|
||
color: '#D10E00',
|
||
width: 1,
|
||
opacity: 1
|
||
},
|
||
data: graphData,
|
||
z: 20
|
||
},
|
||
{
|
||
type: 'heatmap',
|
||
coordinateSystem: 'calendar',
|
||
data: getVirtualData('2024')
|
||
}
|
||
]
|
||
};
|
||
onMounted(() => {
|
||
const doc = document.getElementById("threeContainer")
|
||
const ele = echarts.init(doc)
|
||
ele.setOption(option)
|
||
|
||
let data= transformToGraphData(a)
|
||
console.log(data)
|
||
})
|
||
</script>
|
||
|
||
<template>
|
||
<div class="home" id="threeContainer">
|
||
</div>
|
||
</template>
|
||
<style scoped lang="scss">
|
||
.home {
|
||
width: 100%;
|
||
height: 100vh;
|
||
background-color: #4a4b4b;
|
||
}
|
||
</style> |