files/HomeView.vue
2024-12-10 21:22:00 +08:00

212 lines
4.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>