/**
* 沪深港通资金流向监控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();
}
}
});