<!-- 访客趋势图组件 -->
<template>
	<div class="visitor-trend">
		<div ref="chartRef" style="width: 100%; height: 300px"></div>
		<div style="position: absolute; top: 20px; right: 0">
			<el-select v-model="value" style="width: 84px" @change="initChart">
				<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
			</el-select>
		</div>
	</div>
</template>

<script setup lang="ts" name="keywordFrequency">
import { ref, onMounted, onUnmounted, watch } from 'vue';
import * as echarts from 'echarts';

const chartData = ref([
	{ name: '下载', value: 30, color: '#ff6384' },
	{ name: '宅六', value: 10, color: '#4bc0c0' },

	{ name: '张三', value: 20, color: '#36a2eb' },
	{ name: '里斯', value: 25, color: '#cc65fe' },
	{ name: '王五', value: 15, color: '#ffce56' },
]);

	const value = ref('7');
	const options = [
		{
			value: '7',
			label: '7天',
			selected: true,
		},
		{
			value: '30',
			label: '30天',
		},
	];

const chartRef = ref(null);
let chartInstance: echarts.ECharts | null = null;
console.log(chartInstance);

// 初始化图表
const initChart = () => {
	if (!chartRef.value) return;

	// 销毁旧实例（如果存在）
	if (chartInstance) {
		chartInstance.dispose();
	}

	// 创建新实例
	chartInstance = echarts.init(chartRef.value);
	console.log(chartInstance);

	// 处理数据
	const colorPalette = [
  '#ff6384', '#4bc0c0', '#36a2eb', '#cc65fe', '#ffce56',
  '#f87171', '#fbbf24', '#34d399', '#60a5fa', '#a78bfa',
  '#f472b6', '#facc15', '#2dd4bf', '#818cf8', '#f59e42',
  '#eab308', '#10b981', '#3b82f6', '#6366f1', '#f43f5e',
  '#a3e635', '#fcd34d', '#fca5a5', '#c084fc', '#f9fafb'
];

const realData = chartData.value;
const totalBubbles = 25;
const scatterData: any[] = [];
const minRadius = 10;
const maxRadius = 18;
const padding = 2; // 气泡之间的最小间距
const maxTry = 1000;

function isOverlap(x: number, y: number, r: number, arr: any[]) {
  for (const b of arr) {
    const dx = x - b.value[0];
    const dy = y - b.value[1];
    const dist = Math.sqrt(dx * dx + dy * dy);
    if (dist < r + b.value[2] + padding) return true;
  }
  return false;
}

function placeBubble(radius: number, arr: any[]): [number, number] {
  let tryCount = 0;
  while (tryCount < maxTry) {
    const x = Math.random() * (100 - 2 * radius) + radius;
    const y = Math.random() * (100 - 2 * radius) + radius;
    if (!isOverlap(x, y, radius, arr)) return [x, y];
    tryCount++;
  }
  // fallback: 网格法兜底
  return [Math.random() * 100, Math.random() * 100];
}

// 先放真实数据
realData.forEach((item, i) => {
  const radius = maxRadius;
  const [x, y] = placeBubble(radius, scatterData);
  scatterData.push({
    value: [x, y, radius],
    itemStyle: { color: colorPalette[i % colorPalette.length] },
    name: `${item.name}\n${item.value}`,
  });
});

// 填充空白气泡
for (let j = realData.length; j < totalBubbles; j++) {
  const radius = minRadius + Math.random() * (maxRadius - minRadius) * 0.5;
  const [x, y] = placeBubble(radius, scatterData);
  scatterData.push({
    value: [x, y, radius],
    itemStyle: { color: colorPalette[j % colorPalette.length] },
    name: '',
    label: { show: false }
  });
}

	// 配置项
	const option = {
		tooltip: {
			trigger: 'item',
			formatter: '{b}',
		},
		grid: {
            top: '40%',
		},
		xAxis: { show: false },
		yAxis: { show: false },
		series: [
			{
				type: 'scatter',
				data: scatterData,
				symbolSize: (value: any) => {
					return value[2] * 3; // 根据值计算气泡大小
				},
				label: {
					show: true,
					position: 'inside',
					color: '#fff',
					fontSize: 14,
					formatter: '{b}',
				},
				emphasis: {
					label: { show: true },
				},
			},
		],
	};

	// 设置配置项
	chartInstance.setOption(option);

	// 添加响应式
	window.addEventListener('resize', handleResize);
};

// 响应窗口大小变化
const handleResize = () => {
	if (chartInstance) {
		chartInstance.resize();
	}
};

// 生命周期钩子
onMounted(() => {
	initChart();
});

onUnmounted(() => {
	if (chartInstance) {
		window.removeEventListener('resize', handleResize);
		chartInstance.dispose();
		chartInstance = null;
	}
});
</script>

<style scoped lang="scss">
.bubble-chart-container {
	width: 465px;
	height: 330px;
	min-height: 330px;
}

.chart {
	width: 100%;
	height: 100%;
}
</style>    
