/** * 沪深港通资金流向监控JS */ document.addEventListener('DOMContentLoaded', function() { // 初始化图表 let northChart = null; let southChart = null; // 初始化图表函数,确保DOM元素存在 function initCharts() { try { const northChartDom = document.getElementById('northChart'); const southChartDom = document.getElementById('southChart'); if (northChartDom && !northChart) { try { northChart = echarts.init(northChartDom); console.log('北向资金图表初始化成功'); } catch (e) { console.error('北向资金图表初始化失败:', e); } } if (southChartDom && !southChart) { try { southChart = echarts.init(southChartDom); console.log('南向资金图表初始化成功'); } catch (e) { console.error('南向资金图表初始化失败:', e); } } return northChart && southChart; } catch (e) { console.error('图表初始化过程中发生错误:', e); return false; } } // 确保DOM加载完毕后初始化图表 // 使用setTimeout确保DOM元素完全渲染 setTimeout(function() { if (!initCharts()) { console.log('首次初始化图表不成功,将在数据加载时再次尝试'); } // 开始加载数据 loadData(); // 设置自动刷新 (每分钟刷新一次) setInterval(loadData, 60000); }, 100); // 设置图表自适应 window.addEventListener('resize', function() { if (northChart) { try { northChart.resize(); } catch (e) { console.error('北向资金图表调整大小失败:', e); } } if (southChart) { try { southChart.resize(); } catch (e) { console.error('南向资金图表调整大小失败:', e); } } }); // 刷新按钮事件 const refreshBtn = document.getElementById('refreshBtn'); if (refreshBtn) { refreshBtn.addEventListener('click', function() { loadData(); }); } /** * 加载北向和南向资金数据 */ function loadData() { // 确保图表已经初始化 initCharts(); // 显示加载中状态 showLoading(true); console.log('开始加载北向资金数据...'); // 获取北向资金数据 (从香港流入A股的资金) fetch('/api/hsgt/northbound') .then(response => { if (!response.ok) { return response.json().then(data => { throw new Error(data.message || '获取北向资金数据失败'); }); } return response.json(); }) .then(data => { console.log('北向资金数据获取成功:', data.status); if (data.status === 'success' && data.data && data.data.success) { // 检查数据结构 console.log('北向资金数据结构:', { hasTimeArray: Array.isArray(data.data.times), timeLength: data.data.times ? data.data.times.length : 0, hasDataObj: !!data.data.data, totalLength: data.data.data && data.data.data.total ? data.data.data.total.length : 0, hasCurrent: !!data.data.current }); // 渲染北向资金数据 renderNorthboundData(data.data); } else { const errorMessage = data.data && data.data.message ? data.data.message : (data.message || '北向资金数据格式错误'); showError('北向资金数据获取失败: ' + errorMessage); // 显示空数据状态 renderEmptyNorthboundChart(); } }) .catch(error => { showError('请求北向资金数据错误: ' + error.message); console.error('北向资金数据请求异常:', error); // 显示空数据状态 renderEmptyNorthboundChart(); }) .finally(() => { // 无论成功失败,都开始请求南向资金数据 loadSouthboundData(); }); } /** * 渲染空的北向资金图表 */ function renderEmptyNorthboundChart() { if (!northChart) return; // 更新统计卡片为暂无数据 updateStatCard('northTotal', null, '暂无数据'); updateStatCard('northSH', null, '暂无数据'); updateStatCard('northSZ', null, '暂无数据'); // 初始化一个简单的图表提示暂无数据 northChart.setOption({ title: { text: '陆股通资金流向(北向)', left: 'center', top: 0 }, graphic: { elements: [{ type: 'text', left: 'center', top: 'middle', style: { text: '暂无数据', fontSize: 20, fill: '#999' } }] } }, true); } /** * 加载南向资金数据 */ function loadSouthboundData() { console.log('开始加载南向资金数据...'); fetch('/api/hsgt/southbound') .then(response => { if (!response.ok) { return response.json().then(data => { throw new Error(data.message || '获取南向资金数据失败'); }); } return response.json(); }) .then(data => { console.log('南向资金数据获取成功:', data.status); if (data.status === 'success' && data.data && data.data.success) { // 检查数据结构 console.log('南向资金数据结构:', { hasTimeArray: Array.isArray(data.data.times), timeLength: data.data.times ? data.data.times.length : 0, hasDataObj: !!data.data.data, totalLength: data.data.data && data.data.data.total ? data.data.data.total.length : 0, hasCurrent: !!data.data.current }); // 渲染南向资金数据 renderSouthboundData(data.data); } else { const errorMessage = data.data && data.data.message ? data.data.message : (data.message || '南向资金数据格式错误'); showError('南向资金数据获取失败: ' + errorMessage); // 显示空数据状态 renderEmptySouthboundChart(); } }) .catch(error => { showError('请求南向资金数据错误: ' + error.message); console.error('南向资金数据请求异常:', error); // 显示空数据状态 renderEmptySouthboundChart(); }) .finally(() => { // 隐藏加载中状态 showLoading(false); }); } /** * 渲染空的南向资金图表 */ function renderEmptySouthboundChart() { if (!southChart) return; // 更新统计卡片为暂无数据 updateStatCard('southTotal', null, '暂无数据'); updateStatCard('southHKSH', null, '暂无数据'); updateStatCard('southHKSZ', null, '暂无数据'); // 初始化一个简单的图表提示暂无数据 southChart.setOption({ title: { text: '港股通资金流向(南向)', left: 'center', top: 0 }, graphic: { elements: [{ type: 'text', left: 'center', top: 'middle', style: { text: '暂无数据', fontSize: 20, fill: '#999' } }] } }, true); } /** * 渲染北向资金数据 (从香港流入A股的资金) */ function renderNorthboundData(data) { if (!northChart) return; try { // 验证数据有效性 if (!data || !data.data || !data.times || !data.current) { renderEmptyNorthboundChart(); return; } // 准备简化的图表数据 const times = data.times; const seriesData = []; // 处理北向资金总量 if (data.data.total && Array.isArray(data.data.total) && data.data.total.length > 0) { seriesData.push({ name: '北向资金', type: 'line', data: data.data.total, lineStyle: {width: 3} }); } // 处理沪股通 if (data.data.sh && Array.isArray(data.data.sh) && data.data.sh.length > 0) { seriesData.push({ name: '沪股通', type: 'line', data: data.data.sh }); } // 处理深股通 if (data.data.sz && Array.isArray(data.data.sz) && data.data.sz.length > 0) { seriesData.push({ name: '深股通', type: 'line', data: data.data.sz }); } // 如果没有有效的系列数据,显示空图表 if (seriesData.length === 0) { renderEmptyNorthboundChart(); return; } // 更新统计卡片 updateStatCard('northTotal', data.current.total); updateStatCard('northSH', data.current.sh); updateStatCard('northSZ', data.current.sz); // 更新时间 const updateTimeElem = document.getElementById('updateTime'); if (updateTimeElem) { updateTimeElem.textContent = '最后更新时间: ' + data.update_time; } // 创建简单的图表配置 const option = { title: { text: '陆股通资金流向(北向)', left: 'center', top: 0 }, tooltip: { trigger: 'axis', formatter: function(params) { if (!params || params.length === 0) return ''; const time = params[0].axisValue; let result = `${time}
`; params.forEach(param => { if (param && param.value !== undefined) { const value = param.value; const color = param.color; const marker = ``; let valueText = value !== null ? value.toFixed(2) : 'N/A'; if (value > 0) valueText = '+' + valueText; result += `${marker}${param.seriesName}: ${valueText} 亿
`; } }); return result; } }, legend: { data: seriesData.map(item => item.name), top: 30 }, grid: { left: '3%', right: '4%', bottom: '3%', top: 80, containLabel: true }, xAxis: { type: 'category', boundaryGap: false, data: times, axisLabel: { rotate: 45 } }, yAxis: { type: 'value', name: '净流入金额(亿元)', axisLabel: { formatter: function(value) { return value.toFixed(1); } } }, series: seriesData, color: ['#ec0000', '#1e88e5', '#ff9800'] }; // 安全地设置图表 if (northChart && northChart.setOption) { northChart.setOption(option, true); } else { console.error('北向资金图表实例无效'); const northChartDom = document.getElementById('northChart'); if (northChartDom) { northChart = echarts.init(northChartDom); northChart.setOption(option, true); } } } catch (error) { console.error('设置北向资金图表选项时出错:', error); renderEmptyNorthboundChart(); } } /** * 渲染南向资金数据 (从内地流入港股的资金) */ function renderSouthboundData(data) { if (!southChart) return; try { // 验证数据有效性 if (!data || !data.data || !data.times || !data.current) { renderEmptySouthboundChart(); return; } // 准备简化的图表数据 const times = data.times; const seriesData = []; // 处理南向资金总量 if (data.data.total && Array.isArray(data.data.total) && data.data.total.length > 0) { seriesData.push({ name: '南向资金', type: 'line', data: data.data.total, lineStyle: {width: 3} }); } // 处理沪市港股通 if (data.data.hk_sh && Array.isArray(data.data.hk_sh) && data.data.hk_sh.length > 0) { seriesData.push({ name: '沪市港股通', type: 'line', data: data.data.hk_sh }); } // 处理深市港股通 if (data.data.hk_sz && Array.isArray(data.data.hk_sz) && data.data.hk_sz.length > 0) { seriesData.push({ name: '深市港股通', type: 'line', data: data.data.hk_sz }); } // 如果没有有效的系列数据,显示空图表 if (seriesData.length === 0) { renderEmptySouthboundChart(); return; } // 更新统计卡片 updateStatCard('southTotal', data.current.total); updateStatCard('southHKSH', data.current.hk_sh); updateStatCard('southHKSZ', data.current.hk_sz); // 创建简单的图表配置 const option = { title: { text: '港股通资金流向(南向)', left: 'center', top: 0 }, tooltip: { trigger: 'axis', formatter: function(params) { if (!params || params.length === 0) return ''; const time = params[0].axisValue; let result = `${time}
`; params.forEach(param => { if (param && param.value !== undefined) { const value = param.value; const color = param.color; const marker = ``; let valueText = value !== null ? value.toFixed(2) : 'N/A'; if (value > 0) valueText = '+' + valueText; result += `${marker}${param.seriesName}: ${valueText} 亿
`; } }); return result; } }, legend: { data: seriesData.map(item => item.name), top: 30 }, grid: { left: '3%', right: '4%', bottom: '3%', top: 80, containLabel: true }, xAxis: { type: 'category', boundaryGap: false, data: times, axisLabel: { rotate: 45 } }, yAxis: { type: 'value', name: '净流入金额(亿元)', axisLabel: { formatter: function(value) { return value.toFixed(1); } } }, series: seriesData, color: ['#ec0000', '#1e88e5', '#ff9800'] }; // 安全地设置图表 if (southChart && southChart.setOption) { southChart.setOption(option, true); } else { console.error('南向资金图表实例无效'); const southChartDom = document.getElementById('southChart'); if (southChartDom) { southChart = echarts.init(southChartDom); southChart.setOption(option, true); } } } catch (error) { console.error('设置南向资金图表选项时出错:', error); renderEmptySouthboundChart(); } } /** * 更新统计卡片 */ function updateStatCard(id, value, customText) { const statCard = document.getElementById(id); if (!statCard) return; const statValue = statCard.querySelector('.stat-value'); if (!statValue) return; if (customText) { statValue.textContent = customText; statValue.classList.remove('money-inflow', 'money-outflow'); return; } if (value === null || value === undefined) { statValue.textContent = '--'; statValue.classList.remove('money-inflow', 'money-outflow'); return; } // 格式化显示,保留两位小数 const formattedValue = value.toFixed(2); // 根据正负值设置样式 if (value > 0) { statValue.textContent = '+' + formattedValue; statValue.classList.add('money-inflow'); statValue.classList.remove('money-outflow'); } else if (value < 0) { statValue.textContent = formattedValue; statValue.classList.add('money-outflow'); statValue.classList.remove('money-inflow'); } else { statValue.textContent = formattedValue; statValue.classList.remove('money-inflow', 'money-outflow'); } } /** * 显示错误信息 */ function showError(message) { console.error(message); // 可以添加Toast或其他UI提示 } /** * 显示/隐藏加载状态 */ function showLoading(isLoading) { if (!northChart || !southChart) return; // 实现加载中状态显示 if (isLoading) { northChart.showLoading({text: '加载中...'}); southChart.showLoading({text: '加载中...'}); } else { northChart.hideLoading(); southChart.hideLoading(); } } });