均线系统修理好了
This commit is contained in:
+256
-112
@@ -466,6 +466,23 @@
|
|||||||
.ma-config-btn-secondary:hover {
|
.ma-config-btn-secondary:hover {
|
||||||
background-color: #5c636a;
|
background-color: #5c636a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ma-line-preview {
|
||||||
|
width: 100%;
|
||||||
|
height: 30px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-top: 8px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ma-line-preview svg {
|
||||||
|
width: 80%;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -6820,19 +6837,48 @@
|
|||||||
|
|
||||||
// 显示均线配置弹窗
|
// 显示均线配置弹窗
|
||||||
function showMAConfig() {
|
function showMAConfig() {
|
||||||
|
console.log('📂 显示均线配置弹窗,设置为添加模式');
|
||||||
$('#maConfigModal').css('display', 'flex');
|
$('#maConfigModal').css('display', 'flex');
|
||||||
|
|
||||||
// 重置表单
|
// 重置表单
|
||||||
$('#maType').val('SMA');
|
$('#maType').val('SMA');
|
||||||
$('#maLength').val(20);
|
$('#maLength').val(20);
|
||||||
$('#maSource').val('close');
|
$('#maSource').val('close');
|
||||||
$('#maSmoothType').val('none');
|
$('#maSmoothType').val('none');
|
||||||
$('#maSmoothLength').val(3).prop('disabled', true);
|
$('#maSmoothLength').val(3).prop('disabled', true);
|
||||||
|
$('#maLineWidth').val(2);
|
||||||
|
$('#maLineStyle').val(0);
|
||||||
$('#maColor').val(getRandomColor());
|
$('#maColor').val(getRandomColor());
|
||||||
|
|
||||||
|
// 移除所有现有的点击事件,避免事件冲突
|
||||||
|
$('#maConfigSubmitBtn').off('click');
|
||||||
|
|
||||||
|
// 设置按钮为添加模式
|
||||||
|
$('#maConfigSubmitBtn').text('添加').on('click', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
console.log('🖱️ 点击了添加按钮(来自showMAConfig),准备添加新均线');
|
||||||
|
addMovingAverage();
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('🔄 按钮已设置为添加模式');
|
||||||
|
|
||||||
|
// 更新预览
|
||||||
|
setTimeout(updateLinePreview, 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 隐藏均线配置弹窗
|
// 隐藏均线配置弹窗
|
||||||
function hideMAConfig() {
|
function hideMAConfig() {
|
||||||
|
console.log('🔒 关闭均线配置弹窗');
|
||||||
$('#maConfigModal').css('display', 'none');
|
$('#maConfigModal').css('display', 'none');
|
||||||
|
|
||||||
|
// 移除所有现有的点击事件
|
||||||
|
$('#maConfigSubmitBtn').off('click');
|
||||||
|
|
||||||
|
// 恢复按钮为添加模式 - 但不立即绑定事件,防止意外触发
|
||||||
|
$('#maConfigSubmitBtn').text('添加');
|
||||||
|
|
||||||
|
console.log('🔄 按钮已重置为添加模式,等待用户主动点击"添加均线"按钮');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取随机颜色
|
// 获取随机颜色
|
||||||
@@ -6844,6 +6890,10 @@
|
|||||||
|
|
||||||
// 添加均线
|
// 添加均线
|
||||||
function addMovingAverage() {
|
function addMovingAverage() {
|
||||||
|
console.log('🚨🚨🚨 ➕ 警告:addMovingAverage函数被调用了!!!');
|
||||||
|
console.log('📊 添加前均线配置数量:', movingAverages.length);
|
||||||
|
console.log('🔍 调用堆栈:', new Error().stack);
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
id: ++maIdCounter,
|
id: ++maIdCounter,
|
||||||
type: $('#maType').val(),
|
type: $('#maType').val(),
|
||||||
@@ -6851,10 +6901,20 @@
|
|||||||
source: $('#maSource').val(),
|
source: $('#maSource').val(),
|
||||||
smoothType: $('#maSmoothType').val(),
|
smoothType: $('#maSmoothType').val(),
|
||||||
smoothLength: parseInt($('#maSmoothLength').val()),
|
smoothLength: parseInt($('#maSmoothLength').val()),
|
||||||
|
lineWidth: parseInt($('#maLineWidth').val()),
|
||||||
|
lineStyle: parseInt($('#maLineStyle').val()),
|
||||||
color: $('#maColor').val(),
|
color: $('#maColor').val(),
|
||||||
visible: true
|
visible: true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
console.log('📝 新均线配置:', {
|
||||||
|
id: config.id,
|
||||||
|
type: config.type,
|
||||||
|
length: config.length,
|
||||||
|
source: config.source,
|
||||||
|
color: config.color
|
||||||
|
});
|
||||||
|
|
||||||
// 验证输入
|
// 验证输入
|
||||||
if (config.length < 1 || config.length > 200) {
|
if (config.length < 1 || config.length > 200) {
|
||||||
alert('均线长度必须在1-200之间');
|
alert('均线长度必须在1-200之间');
|
||||||
@@ -6867,11 +6927,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
movingAverages.push(config);
|
movingAverages.push(config);
|
||||||
|
|
||||||
|
console.log('📊 添加后均线配置数量:', movingAverages.length);
|
||||||
|
|
||||||
hideMAConfig();
|
hideMAConfig();
|
||||||
|
|
||||||
// 重新绘制图表以包含新均线
|
// 直接使用前端数据计算和添加均线,不请求后台
|
||||||
if (typeof updateChart === 'function') {
|
if (tvWidget.mainChart && currentData && currentData.kline_data) {
|
||||||
updateChart();
|
const candles = getCurrentCandleData();
|
||||||
|
addMovingAveragesToChart(candles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7003,6 +7067,11 @@
|
|||||||
const smoothText = ma.smoothType !== 'none' ?
|
const smoothText = ma.smoothType !== 'none' ?
|
||||||
`, ${ma.smoothType}(${ma.smoothLength})` : '';
|
`, ${ma.smoothType}(${ma.smoothLength})` : '';
|
||||||
|
|
||||||
|
// 获取线条样式描述
|
||||||
|
const lineStyleNames = ['实线', '点线', '虚线', '大虚线'];
|
||||||
|
const styleText = ma.lineWidth && ma.lineStyle !== undefined ?
|
||||||
|
` ${ma.lineWidth}px ${lineStyleNames[ma.lineStyle] || '实线'}` : '';
|
||||||
|
|
||||||
// 显示所有均线(包括隐藏的),但用不同样式区分
|
// 显示所有均线(包括隐藏的),但用不同样式区分
|
||||||
const itemStyle = ma.visible ? '' : 'opacity: 0.5;';
|
const itemStyle = ma.visible ? '' : 'opacity: 0.5;';
|
||||||
const eyeIcon = ma.visible ? 'bi-eye' : 'bi-eye-slash';
|
const eyeIcon = ma.visible ? 'bi-eye' : 'bi-eye-slash';
|
||||||
@@ -7011,17 +7080,17 @@
|
|||||||
<div class="ma-item" data-ma-id="${ma.id}" style="${itemStyle}">
|
<div class="ma-item" data-ma-id="${ma.id}" style="${itemStyle}">
|
||||||
<div class="ma-info">
|
<div class="ma-info">
|
||||||
<div class="ma-color-indicator" style="background-color: ${ma.color}"></div>
|
<div class="ma-color-indicator" style="background-color: ${ma.color}"></div>
|
||||||
<span class="ma-label">${ma.type}(${ma.length})${smoothText}</span>
|
<span class="ma-label">${ma.type}(${ma.length})${smoothText}${styleText}</span>
|
||||||
<span class="ma-value">${ma.visible ? latestValue : '--'}</span>
|
<span class="ma-value">${ma.visible ? latestValue : '--'}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="ma-actions">
|
<div class="ma-actions">
|
||||||
<button class="ma-action-btn" onclick="toggleMAVisibility(${ma.id})" title="${ma.visible ? '隐藏' : '显示'}">
|
<button class="ma-action-btn" onclick="toggleMAVisibility('${ma.id}')" title="${ma.visible ? '隐藏' : '显示'}">
|
||||||
<i class="bi ${eyeIcon}"></i>
|
<i class="bi ${eyeIcon}"></i>
|
||||||
</button>
|
</button>
|
||||||
<button class="ma-action-btn" onclick="configMA(${ma.id})" title="配置">
|
<button class="ma-action-btn" onclick="configMA('${ma.id}')" title="配置">
|
||||||
<i class="bi bi-gear"></i>
|
<i class="bi bi-gear"></i>
|
||||||
</button>
|
</button>
|
||||||
<button class="ma-action-btn" onclick="deleteMA(${ma.id})" title="删除">
|
<button class="ma-action-btn" onclick="deleteMA('${ma.id}')" title="删除">
|
||||||
<i class="bi bi-trash"></i>
|
<i class="bi bi-trash"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -7043,83 +7112,88 @@
|
|||||||
|
|
||||||
// 切换均线可见性
|
// 切换均线可见性
|
||||||
function toggleMAVisibility(maId) {
|
function toggleMAVisibility(maId) {
|
||||||
const ma = movingAverages.find(m => m.id === maId);
|
console.log('👁️ 切换均线可见性,ID:', maId, 'Type:', typeof maId);
|
||||||
|
|
||||||
|
const ma = movingAverages.find(m => m.id == maId); // 使用==而不是===来兼容类型转换
|
||||||
if (ma) {
|
if (ma) {
|
||||||
|
console.log('📝 找到均线,当前可见性:', ma.visible);
|
||||||
ma.visible = !ma.visible;
|
ma.visible = !ma.visible;
|
||||||
|
console.log('✅ 切换后可见性:', ma.visible);
|
||||||
|
|
||||||
// 如果图表已初始化,直接更新均线显示
|
// 直接使用前端数据重新计算均线
|
||||||
if (tvWidget.mainChart && currentData && currentData.kline_data) {
|
if (tvWidget.mainChart && currentData && currentData.kline_data) {
|
||||||
// 获取K线数据
|
const candles = getCurrentCandleData();
|
||||||
const useElementPeriod = $('#elementPeriodKline').is(':checked') &&
|
|
||||||
currentData.element_kline_data &&
|
|
||||||
Array.isArray(currentData.element_kline_data);
|
|
||||||
|
|
||||||
let candles = [];
|
|
||||||
if (useElementPeriod) {
|
|
||||||
candles = currentData.element_kline_data.map((kline) => {
|
|
||||||
const date = new Date(kline.date);
|
|
||||||
const timestamp = date.getTime() / 1000;
|
|
||||||
return {
|
|
||||||
time: timestamp,
|
|
||||||
open: parseFloat(kline.open),
|
|
||||||
high: parseFloat(kline.high),
|
|
||||||
low: parseFloat(kline.low),
|
|
||||||
close: parseFloat(kline.close),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
candles = currentData.kline_data.map((kline) => {
|
|
||||||
const date = new Date(kline.date);
|
|
||||||
const timestamp = date.getTime() / 1000;
|
|
||||||
return {
|
|
||||||
time: timestamp,
|
|
||||||
open: parseFloat(kline.open),
|
|
||||||
high: parseFloat(kline.high),
|
|
||||||
low: parseFloat(kline.low),
|
|
||||||
close: parseFloat(kline.close),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 重新添加均线到图表
|
|
||||||
addMovingAveragesToChart(candles);
|
addMovingAveragesToChart(candles);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// 如果图表未初始化,重新加载整个图表
|
console.error('❌ 未找到要切换可见性的均线,ID:', maId);
|
||||||
if (typeof updateChart === 'function') {
|
|
||||||
updateChart();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 配置均线
|
// 配置均线
|
||||||
function configMA(maId) {
|
function configMA(maId) {
|
||||||
const ma = movingAverages.find(m => m.id === maId);
|
console.log('⚙️ 开始配置均线,ID:', maId, 'Type:', typeof maId);
|
||||||
if (ma) {
|
console.log('📊 当前所有均线ID:', movingAverages.map(m => ({id: m.id, type: typeof m.id})));
|
||||||
|
|
||||||
|
const ma = movingAverages.find(m => m.id == maId); // 使用==而不是===来兼容类型转换
|
||||||
|
if (!ma) {
|
||||||
|
console.error('❌ 未找到要配置的均线,ID:', maId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('📝 找到要配置的均线:', ma.type, ma.length, ma.color);
|
||||||
|
|
||||||
// 填充表单
|
// 填充表单
|
||||||
$('#maType').val(ma.type);
|
$('#maType').val(ma.type);
|
||||||
$('#maLength').val(ma.length);
|
$('#maLength').val(ma.length);
|
||||||
$('#maSource').val(ma.source);
|
$('#maSource').val(ma.source);
|
||||||
$('#maSmoothType').val(ma.smoothType);
|
$('#maSmoothType').val(ma.smoothType);
|
||||||
$('#maSmoothLength').val(ma.smoothLength);
|
$('#maSmoothLength').val(ma.smoothLength);
|
||||||
|
$('#maLineWidth').val(ma.lineWidth || 2);
|
||||||
|
$('#maLineStyle').val(ma.lineStyle || 0);
|
||||||
$('#maColor').val(ma.color);
|
$('#maColor').val(ma.color);
|
||||||
|
|
||||||
// 启用/禁用平滑长度输入
|
// 启用/禁用平滑长度输入
|
||||||
$('#maSmoothLength').prop('disabled', ma.smoothType === 'none');
|
$('#maSmoothLength').prop('disabled', ma.smoothType === 'none');
|
||||||
|
|
||||||
|
// 移除所有现有的点击事件,避免事件冲突
|
||||||
|
$('#maConfigSubmitBtn').off('click');
|
||||||
|
|
||||||
// 修改按钮为更新模式
|
// 修改按钮为更新模式
|
||||||
$('.ma-config-btn-primary').text('更新').off('click').on('click', function() {
|
$('#maConfigSubmitBtn').text('更新').on('click', (function(capturedMaId) {
|
||||||
updateMovingAverage(maId);
|
return function(e) {
|
||||||
});
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
console.log('🖱️ 点击了更新按钮,准备更新ID:', capturedMaId);
|
||||||
|
console.log('🔍 捕获的ID类型:', typeof capturedMaId);
|
||||||
|
updateMovingAverage(capturedMaId);
|
||||||
|
};
|
||||||
|
})(maId));
|
||||||
|
|
||||||
|
console.log('🔄 按钮已切换为更新模式');
|
||||||
|
|
||||||
$('#maConfigModal').css('display', 'flex');
|
$('#maConfigModal').css('display', 'flex');
|
||||||
}
|
|
||||||
|
// 更新预览
|
||||||
|
setTimeout(updateLinePreview, 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新均线
|
// 更新均线
|
||||||
function updateMovingAverage(maId) {
|
function updateMovingAverage(maId) {
|
||||||
const ma = movingAverages.find(m => m.id === maId);
|
console.log('🔄 开始更新均线,ID:', maId, 'Type:', typeof maId);
|
||||||
if (ma) {
|
console.log('📊 更新前均线配置数量:', movingAverages.length);
|
||||||
|
console.log('📊 当前所有均线:', movingAverages.map(m => ({id: m.id, type: typeof m.id, maType: m.type, length: m.length, color: m.color})));
|
||||||
|
|
||||||
|
const ma = movingAverages.find(m => m.id == maId); // 使用==而不是===来兼容类型转换
|
||||||
|
if (!ma) {
|
||||||
|
console.error('❌ 未找到要更新的均线配置,ID:', maId);
|
||||||
|
console.error('❌ 可用的均线ID:', movingAverages.map(m => m.id));
|
||||||
|
alert('错误:未找到要更新的均线配置!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('📝 找到要更新的均线:', ma.type, ma.length, ma.color);
|
||||||
|
|
||||||
// 验证输入
|
// 验证输入
|
||||||
const newLength = parseInt($('#maLength').val());
|
const newLength = parseInt($('#maLength').val());
|
||||||
const newSmoothLength = parseInt($('#maSmoothLength').val());
|
const newSmoothLength = parseInt($('#maSmoothLength').val());
|
||||||
@@ -7135,67 +7209,67 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 记录更新前的配置
|
||||||
|
console.log('🔧 更新前配置:', {
|
||||||
|
type: ma.type,
|
||||||
|
length: ma.length,
|
||||||
|
source: ma.source,
|
||||||
|
color: ma.color
|
||||||
|
});
|
||||||
|
|
||||||
// 更新配置
|
// 更新配置
|
||||||
ma.type = $('#maType').val();
|
ma.type = $('#maType').val();
|
||||||
ma.length = newLength;
|
ma.length = newLength;
|
||||||
ma.source = $('#maSource').val();
|
ma.source = $('#maSource').val();
|
||||||
ma.smoothType = newSmoothType;
|
ma.smoothType = newSmoothType;
|
||||||
ma.smoothLength = newSmoothLength;
|
ma.smoothLength = newSmoothLength;
|
||||||
|
ma.lineWidth = parseInt($('#maLineWidth').val());
|
||||||
|
ma.lineStyle = parseInt($('#maLineStyle').val());
|
||||||
ma.color = $('#maColor').val();
|
ma.color = $('#maColor').val();
|
||||||
|
|
||||||
|
// 记录更新后的配置
|
||||||
|
console.log('✅ 更新后配置:', {
|
||||||
|
type: ma.type,
|
||||||
|
length: ma.length,
|
||||||
|
source: ma.source,
|
||||||
|
color: ma.color
|
||||||
|
});
|
||||||
|
console.log('📊 更新后均线配置数量:', movingAverages.length);
|
||||||
|
|
||||||
hideMAConfig();
|
hideMAConfig();
|
||||||
|
|
||||||
// 恢复按钮为添加模式
|
// 直接使用前端数据重新计算均线
|
||||||
$('.ma-config-btn-primary').text('添加').off('click').on('click', addMovingAverage);
|
|
||||||
|
|
||||||
// 如果图表已初始化,直接更新均线显示
|
|
||||||
if (tvWidget.mainChart && currentData && currentData.kline_data) {
|
if (tvWidget.mainChart && currentData && currentData.kline_data) {
|
||||||
const useElementPeriod = $('#elementPeriodKline').is(':checked') &&
|
const candles = getCurrentCandleData();
|
||||||
currentData.element_kline_data &&
|
|
||||||
Array.isArray(currentData.element_kline_data);
|
|
||||||
|
|
||||||
let candles = [];
|
|
||||||
if (useElementPeriod) {
|
|
||||||
candles = currentData.element_kline_data.map((kline) => {
|
|
||||||
const date = new Date(kline.date);
|
|
||||||
const timestamp = date.getTime() / 1000;
|
|
||||||
return {
|
|
||||||
time: timestamp,
|
|
||||||
open: parseFloat(kline.open),
|
|
||||||
high: parseFloat(kline.high),
|
|
||||||
low: parseFloat(kline.low),
|
|
||||||
close: parseFloat(kline.close),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
candles = currentData.kline_data.map((kline) => {
|
|
||||||
const date = new Date(kline.date);
|
|
||||||
const timestamp = date.getTime() / 1000;
|
|
||||||
return {
|
|
||||||
time: timestamp,
|
|
||||||
open: parseFloat(kline.open),
|
|
||||||
high: parseFloat(kline.high),
|
|
||||||
low: parseFloat(kline.low),
|
|
||||||
close: parseFloat(kline.close),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
addMovingAveragesToChart(candles);
|
addMovingAveragesToChart(candles);
|
||||||
} else {
|
|
||||||
if (typeof updateChart === 'function') {
|
|
||||||
updateChart();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除均线
|
// 删除均线
|
||||||
function deleteMA(maId) {
|
function deleteMA(maId) {
|
||||||
movingAverages = movingAverages.filter(m => m.id !== maId);
|
console.log('🗑️ 删除均线,ID:', maId, 'Type:', typeof maId);
|
||||||
|
console.log('📊 删除前均线配置数量:', movingAverages.length);
|
||||||
|
|
||||||
// 如果图表已初始化,直接更新均线显示
|
const beforeCount = movingAverages.length;
|
||||||
|
movingAverages = movingAverages.filter(m => m.id != maId); // 使用!=而不是!==来兼容类型转换
|
||||||
|
|
||||||
|
console.log('📊 删除后均线配置数量:', movingAverages.length);
|
||||||
|
console.log('✅ 是否成功删除:', beforeCount > movingAverages.length);
|
||||||
|
|
||||||
|
// 直接使用前端数据重新计算均线
|
||||||
if (tvWidget.mainChart && currentData && currentData.kline_data) {
|
if (tvWidget.mainChart && currentData && currentData.kline_data) {
|
||||||
|
const candles = getCurrentCandleData();
|
||||||
|
addMovingAveragesToChart(candles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前K线数据的辅助函数
|
||||||
|
function getCurrentCandleData() {
|
||||||
|
if (!currentData || !currentData.kline_data) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否使用小周期数据
|
||||||
const useElementPeriod = $('#elementPeriodKline').is(':checked') &&
|
const useElementPeriod = $('#elementPeriodKline').is(':checked') &&
|
||||||
currentData.element_kline_data &&
|
currentData.element_kline_data &&
|
||||||
Array.isArray(currentData.element_kline_data);
|
Array.isArray(currentData.element_kline_data);
|
||||||
@@ -7227,12 +7301,7 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addMovingAveragesToChart(candles);
|
return candles;
|
||||||
} else {
|
|
||||||
if (typeof updateChart === 'function') {
|
|
||||||
updateChart();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加均线到图表
|
// 添加均线到图表
|
||||||
@@ -7241,23 +7310,34 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清除现有的均线系列
|
console.log('🔄 重新绘制均线,当前均线配置数量:', movingAverages.length);
|
||||||
if (tvWidget.series.maSeries) {
|
|
||||||
tvWidget.series.maSeries.forEach(series => {
|
// 强制清除现有的均线系列
|
||||||
|
if (tvWidget.series.maSeries && tvWidget.series.maSeries.length > 0) {
|
||||||
|
console.log('🗑️ 清除现有均线系列:', tvWidget.series.maSeries.length);
|
||||||
|
tvWidget.series.maSeries.forEach((series, index) => {
|
||||||
try {
|
try {
|
||||||
tvWidget.mainChart.removeSeries(series);
|
tvWidget.mainChart.removeSeries(series);
|
||||||
|
console.log('✅ 移除均线系列:', index);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.debug('移除均线系列时出错:', e);
|
console.error('❌ 移除均线系列失败:', index, e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// 重置均线系列数组
|
||||||
tvWidget.series.maSeries = [];
|
tvWidget.series.maSeries = [];
|
||||||
|
|
||||||
// 为每个均线配置创建系列
|
// 为每个均线配置创建系列
|
||||||
movingAverages.forEach(maConfig => {
|
let addedCount = 0;
|
||||||
if (!maConfig.visible) return;
|
movingAverages.forEach((maConfig, index) => {
|
||||||
|
if (!maConfig.visible) {
|
||||||
|
console.log(`⏭️ 跳过隐藏的均线 [${index}]:`, maConfig.type, maConfig.length);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
console.log(`📈 开始创建均线 [${index}]:`, maConfig.type, maConfig.length, maConfig.color);
|
||||||
|
|
||||||
// 计算均线数据
|
// 计算均线数据
|
||||||
const maData = calculateMA(candleData, maConfig.type, maConfig.length, maConfig.source);
|
const maData = calculateMA(candleData, maConfig.type, maConfig.length, maConfig.source);
|
||||||
|
|
||||||
@@ -7269,7 +7349,8 @@
|
|||||||
// 创建线系列
|
// 创建线系列
|
||||||
const maSeries = tvWidget.mainChart.addLineSeries({
|
const maSeries = tvWidget.mainChart.addLineSeries({
|
||||||
color: maConfig.color,
|
color: maConfig.color,
|
||||||
lineWidth: 2,
|
lineWidth: maConfig.lineWidth || 2,
|
||||||
|
lineStyle: maConfig.lineStyle || 0, // 0=实线, 1=点线, 2=虚线, 3=大虚线
|
||||||
title: `${maConfig.type}(${maConfig.length})`,
|
title: `${maConfig.type}(${maConfig.length})`,
|
||||||
lastValueVisible: false,
|
lastValueVisible: false,
|
||||||
priceLineVisible: false,
|
priceLineVisible: false,
|
||||||
@@ -7284,12 +7365,18 @@
|
|||||||
|
|
||||||
// 保存系列引用
|
// 保存系列引用
|
||||||
tvWidget.series.maSeries.push(maSeries);
|
tvWidget.series.maSeries.push(maSeries);
|
||||||
|
addedCount++;
|
||||||
|
|
||||||
|
console.log(`✅ 均线创建成功 [${index}]:`, maConfig.type, maConfig.length, '数据点:', smoothedData.length);
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('添加均线时出错:', e, maConfig);
|
console.error('❌ 添加均线时出错:', e, maConfig);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log(`🎯 均线添加完成,共添加 ${addedCount} 条均线`);
|
||||||
|
console.log('📊 当前图表中的均线系列数量:', tvWidget.series.maSeries.length);
|
||||||
|
|
||||||
// 更新均线面板
|
// 更新均线面板
|
||||||
updateMAPanel();
|
updateMAPanel();
|
||||||
}
|
}
|
||||||
@@ -7300,6 +7387,36 @@
|
|||||||
$('#maSmoothLength').prop('disabled', isNone);
|
$('#maSmoothLength').prop('disabled', isNone);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 更新线条预览
|
||||||
|
function updateLinePreview() {
|
||||||
|
const color = $('#maColor').val();
|
||||||
|
const width = $('#maLineWidth').val();
|
||||||
|
const style = $('#maLineStyle').val();
|
||||||
|
|
||||||
|
const line = $('#previewLine');
|
||||||
|
line.attr('stroke', color);
|
||||||
|
line.attr('stroke-width', width);
|
||||||
|
|
||||||
|
// 设置线条样式
|
||||||
|
switch(parseInt(style)) {
|
||||||
|
case 0: // 实线
|
||||||
|
line.attr('stroke-dasharray', 'none');
|
||||||
|
break;
|
||||||
|
case 1: // 点线
|
||||||
|
line.attr('stroke-dasharray', '2,3');
|
||||||
|
break;
|
||||||
|
case 2: // 虚线
|
||||||
|
line.attr('stroke-dasharray', '5,5');
|
||||||
|
break;
|
||||||
|
case 3: // 大虚线
|
||||||
|
line.attr('stroke-dasharray', '10,5');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听配置变化以更新预览
|
||||||
|
$(document).on('change', '#maColor, #maLineWidth, #maLineStyle', updateLinePreview);
|
||||||
|
|
||||||
// 点击弹窗外部关闭
|
// 点击弹窗外部关闭
|
||||||
$(document).on('click', '#maConfigModal', function(e) {
|
$(document).on('click', '#maConfigModal', function(e) {
|
||||||
if (e.target === this) {
|
if (e.target === this) {
|
||||||
@@ -7409,14 +7526,41 @@
|
|||||||
<label class="ma-config-label">平滑长度</label>
|
<label class="ma-config-label">平滑长度</label>
|
||||||
<input type="number" id="maSmoothLength" class="ma-config-input" value="3" min="1" max="50" disabled>
|
<input type="number" id="maSmoothLength" class="ma-config-input" value="3" min="1" max="50" disabled>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="ma-config-group">
|
||||||
|
<label class="ma-config-label">线条粗细</label>
|
||||||
|
<select id="maLineWidth" class="ma-config-select">
|
||||||
|
<option value="1">细线 (1px)</option>
|
||||||
|
<option value="2" selected>普通 (2px)</option>
|
||||||
|
<option value="3">粗线 (3px)</option>
|
||||||
|
<option value="4">很粗 (4px)</option>
|
||||||
|
<option value="5">超粗 (5px)</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="ma-config-group">
|
||||||
|
<label class="ma-config-label">线条样式</label>
|
||||||
|
<select id="maLineStyle" class="ma-config-select">
|
||||||
|
<option value="0">实线</option>
|
||||||
|
<option value="1">点线</option>
|
||||||
|
<option value="2">虚线</option>
|
||||||
|
<option value="3">大虚线</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
<div class="ma-config-group">
|
<div class="ma-config-group">
|
||||||
<label class="ma-config-label">颜色</label>
|
<label class="ma-config-label">颜色</label>
|
||||||
<input type="color" id="maColor" class="ma-config-input" value="#2962FF">
|
<input type="color" id="maColor" class="ma-config-input" value="#2962FF">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="ma-config-group">
|
||||||
|
<label class="ma-config-label">预览</label>
|
||||||
|
<div id="maLinePreview" class="ma-line-preview">
|
||||||
|
<svg id="previewSvg">
|
||||||
|
<line id="previewLine" x1="10%" y1="50%" x2="90%" y2="50%" stroke="#2962FF" stroke-width="2"/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ma-config-actions">
|
<div class="ma-config-actions">
|
||||||
<button class="ma-config-btn ma-config-btn-secondary" onclick="hideMAConfig()">取消</button>
|
<button class="ma-config-btn ma-config-btn-secondary" onclick="hideMAConfig()">取消</button>
|
||||||
<button class="ma-config-btn ma-config-btn-primary" onclick="addMovingAverage()">添加</button>
|
<button class="ma-config-btn ma-config-btn-primary" id="maConfigSubmitBtn">添加</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user