不能删setupToolTip
This commit is contained in:
@@ -5923,6 +5923,12 @@
|
|||||||
setDefaultTimeRange();
|
setDefaultTimeRange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 添加买卖点提示
|
||||||
|
// 初始化 tooltip 与 U 显示状态
|
||||||
|
window.showUOnMain = $('#toggleUOnMain').is(':checked');
|
||||||
|
window.showUOnElement = $('#toggleUOnElement').is(':checked');
|
||||||
|
setupTooltip(mainChart, [], [], mainChartContainer, volumeChartContainer, atrChartContainer, macdChartContainer, chanMacdChartContainer, volumeChart, atrChart, macdChart, chanMacdChart, showMacd);
|
||||||
|
|
||||||
// 更新EMA52显示
|
// 更新EMA52显示
|
||||||
if (currentData) {
|
if (currentData) {
|
||||||
updateEMA52Display(currentData);
|
updateEMA52Display(currentData);
|
||||||
@@ -6447,7 +6453,266 @@
|
|||||||
}, 200);
|
}, 200);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
function setupTooltip(mainChart, buyMarkers = [], sellMarkers = [], mainChartContainer, volumeChartContainer, atrChartContainer, macdChartContainer, chanMacdChartContainer, volumeChart, atrChart, macdChart, chanMacdChart, showMacd) {
|
||||||
|
// 调试变量
|
||||||
|
window.debugMode = true;
|
||||||
|
// 初始化 U 显示状态(主/次周期分开控制)
|
||||||
|
const isShowUMain = $('#toggleUOnMain').is(':checked');
|
||||||
|
const isShowUElement = $('#toggleUOnElement').is(':checked');
|
||||||
|
window.showUOnMain = isShowUMain;
|
||||||
|
window.showUOnElement = isShowUElement;
|
||||||
|
if (!isShowUMain && !isShowUElement) {
|
||||||
|
// 隐藏时清空子图上的 U 标记
|
||||||
|
if (tvWidget.series && tvWidget.series.chanMacdLineSeries) {
|
||||||
|
try { tvWidget.series.chanMacdLineSeries.setMarkers([]); } catch (e) {}
|
||||||
|
}
|
||||||
|
if (tvWidget.series && tvWidget.series.chanMacdSignalSeries) {
|
||||||
|
try { tvWidget.series.chanMacdSignalSeries.setMarkers([]); } catch (e) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加买卖点悬浮提示元素
|
||||||
|
const tooltipElement = document.createElement('div');
|
||||||
|
tooltipElement.className = 'point-tooltip';
|
||||||
|
// document.body.appendChild(tooltipElement);
|
||||||
|
|
||||||
|
// 添加自定义十字线信息显示
|
||||||
|
const crosshairTooltip = document.createElement('div');
|
||||||
|
crosshairTooltip.className = 'crosshair-tooltip';
|
||||||
|
crosshairTooltip.style.position = 'absolute';
|
||||||
|
crosshairTooltip.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
|
||||||
|
crosshairTooltip.style.color = 'white';
|
||||||
|
crosshairTooltip.style.padding = '5px 10px';
|
||||||
|
crosshairTooltip.style.borderRadius = '4px';
|
||||||
|
crosshairTooltip.style.fontSize = '12px';
|
||||||
|
crosshairTooltip.style.zIndex = '1000';
|
||||||
|
crosshairTooltip.style.pointerEvents = 'none';
|
||||||
|
crosshairTooltip.style.display = 'none';
|
||||||
|
// document.body.appendChild(crosshairTooltip);
|
||||||
|
|
||||||
|
// 添加鼠标悬停事件显示提示
|
||||||
|
if (mainChart) {
|
||||||
|
mainChart.subscribeCrosshairMove(param => {
|
||||||
|
// 十字线同步到其他图表 - 通过DOM元素绘制垂直线实现虚线延长效果
|
||||||
|
if (param.time && param.point && volumeChart) {
|
||||||
|
try {
|
||||||
|
// 清除之前的十字线标记
|
||||||
|
const existingVolumeLines = document.querySelectorAll('.volume-crosshair-line');
|
||||||
|
existingVolumeLines.forEach(line => line.remove());
|
||||||
|
const existingAtrLines = document.querySelectorAll('.atr-crosshair-line');
|
||||||
|
existingAtrLines.forEach(line => line.remove());
|
||||||
|
const existingMacdLines = document.querySelectorAll('.macd-crosshair-line');
|
||||||
|
existingMacdLines.forEach(line => line.remove());
|
||||||
|
const existingChanMacdLines = document.querySelectorAll('.chanmacd-crosshair-line');
|
||||||
|
existingChanMacdLines.forEach(line => line.remove());
|
||||||
|
|
||||||
|
// 获取时间对应的坐标位置
|
||||||
|
const mainTimeCoordinate = mainChart.timeScale().timeToCoordinate(param.time);
|
||||||
|
if (mainTimeCoordinate !== null) {
|
||||||
|
// 获取主图容器的位置
|
||||||
|
const mainChartRect = mainChartContainer.getBoundingClientRect();
|
||||||
|
|
||||||
|
// 在交易量图上绘制垂直线
|
||||||
|
const volumeTimeCoordinate = volumeChart.timeScale().timeToCoordinate(param.time);
|
||||||
|
if (volumeTimeCoordinate !== null) {
|
||||||
|
const volumeChartRect = volumeChartContainer.getBoundingClientRect();
|
||||||
|
const volumeLine = document.createElement('div');
|
||||||
|
volumeLine.className = 'volume-crosshair-line';
|
||||||
|
volumeLine.style.position = 'fixed'; // 改为fixed定位
|
||||||
|
volumeLine.style.left = (volumeChartRect.left + volumeTimeCoordinate) + 'px';
|
||||||
|
volumeLine.style.top = volumeChartRect.top + 'px';
|
||||||
|
volumeLine.style.width = '1px';
|
||||||
|
volumeLine.style.height = volumeChartRect.height + 'px';
|
||||||
|
volumeLine.style.backgroundColor = 'rgba(128, 128, 128, 0.5)';
|
||||||
|
volumeLine.style.borderLeft = '1px dashed rgba(128, 128, 128, 0.5)';
|
||||||
|
volumeLine.style.pointerEvents = 'none';
|
||||||
|
volumeLine.style.zIndex = '1000';
|
||||||
|
document.body.appendChild(volumeLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在ATR图上绘制垂直线
|
||||||
|
if (atrChart && atrChartContainer) {
|
||||||
|
const atrTimeCoordinate = atrChart.timeScale().timeToCoordinate(param.time);
|
||||||
|
if (atrTimeCoordinate !== null) {
|
||||||
|
const atrChartRect = atrChartContainer.getBoundingClientRect();
|
||||||
|
const atrLine = document.createElement('div');
|
||||||
|
atrLine.className = 'atr-crosshair-line';
|
||||||
|
atrLine.style.position = 'fixed'; // 改为fixed定位
|
||||||
|
atrLine.style.left = (atrChartRect.left + atrTimeCoordinate) + 'px';
|
||||||
|
atrLine.style.top = atrChartRect.top + 'px';
|
||||||
|
atrLine.style.width = '1px';
|
||||||
|
atrLine.style.height = atrChartRect.height + 'px';
|
||||||
|
atrLine.style.backgroundColor = 'rgba(128, 128, 128, 0.5)';
|
||||||
|
atrLine.style.borderLeft = '1px dashed rgba(128, 128, 128, 0.5)';
|
||||||
|
atrLine.style.pointerEvents = 'none';
|
||||||
|
atrLine.style.zIndex = '1000';
|
||||||
|
document.body.appendChild(atrLine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果有MACD图,也在MACD图上绘制垂直线
|
||||||
|
if (showMacd && macdChart && macdChartContainer) {
|
||||||
|
const macdTimeCoordinate = macdChart.timeScale().timeToCoordinate(param.time);
|
||||||
|
if (macdTimeCoordinate !== null) {
|
||||||
|
const macdChartRect = macdChartContainer.getBoundingClientRect();
|
||||||
|
const macdLine = document.createElement('div');
|
||||||
|
macdLine.className = 'macd-crosshair-line';
|
||||||
|
macdLine.style.position = 'fixed'; // 改为fixed定位
|
||||||
|
macdLine.style.left = (macdChartRect.left + macdTimeCoordinate) + 'px';
|
||||||
|
macdLine.style.top = macdChartRect.top + 'px';
|
||||||
|
macdLine.style.width = '1px';
|
||||||
|
macdLine.style.height = macdChartRect.height + 'px';
|
||||||
|
macdLine.style.backgroundColor = 'rgba(128, 128, 128, 0.5)';
|
||||||
|
macdLine.style.borderLeft = '1px dashed rgba(128, 128, 128, 0.5)';
|
||||||
|
macdLine.style.pointerEvents = 'none';
|
||||||
|
macdLine.style.zIndex = '1000';
|
||||||
|
document.body.appendChild(macdLine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果有ChanMACD图,也在ChanMACD图上绘制垂直线
|
||||||
|
if (showMacd && chanMacdChart && chanMacdChartContainer) {
|
||||||
|
const chanMacdTimeCoordinate = chanMacdChart.timeScale().timeToCoordinate(param.time);
|
||||||
|
if (chanMacdTimeCoordinate !== null) {
|
||||||
|
const chanMacdChartRect = chanMacdChartContainer.getBoundingClientRect();
|
||||||
|
console.log('ChanMACD图表位置(第二个位置):', {
|
||||||
|
left: chanMacdChartRect.left,
|
||||||
|
top: chanMacdChartRect.top,
|
||||||
|
width: chanMacdChartRect.width,
|
||||||
|
height: chanMacdChartRect.height,
|
||||||
|
timeCoordinate: chanMacdTimeCoordinate
|
||||||
|
});
|
||||||
|
const chanMacdLine = document.createElement('div');
|
||||||
|
chanMacdLine.className = 'chanmacd-crosshair-line';
|
||||||
|
chanMacdLine.style.position = 'fixed';
|
||||||
|
chanMacdLine.style.left = (chanMacdChartRect.left + chanMacdTimeCoordinate) + 'px';
|
||||||
|
chanMacdLine.style.top = chanMacdChartRect.top + 'px';
|
||||||
|
chanMacdLine.style.width = '1px';
|
||||||
|
chanMacdLine.style.height = chanMacdChartRect.height + 'px';
|
||||||
|
chanMacdLine.style.backgroundColor = 'rgba(128, 128, 128, 0.5)';
|
||||||
|
chanMacdLine.style.borderLeft = '1px dashed rgba(128, 128, 128, 0.5)';
|
||||||
|
chanMacdLine.style.pointerEvents = 'none';
|
||||||
|
chanMacdLine.style.zIndex = '1000';
|
||||||
|
document.body.appendChild(chanMacdLine);
|
||||||
|
console.log('ChanMACD垂直线已创建(第二个位置),位置:', chanMacdLine.style.left, chanMacdLine.style.top);
|
||||||
|
} else {
|
||||||
|
console.log('ChanMACD时间坐标为空(第二个位置)');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log('ChanMACD图表条件不满足(第二个位置):', {
|
||||||
|
showMacd: showMacd,
|
||||||
|
hasChanMacdChart: !!chanMacdChart,
|
||||||
|
hasChanMacdChartContainer: !!chanMacdChartContainer
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.debug('十字线同步出错:', e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 当十字线离开时,清除垂直线
|
||||||
|
try {
|
||||||
|
const existingVolumeLines = document.querySelectorAll('.volume-crosshair-line');
|
||||||
|
existingVolumeLines.forEach(line => line.remove());
|
||||||
|
const existingAtrLines = document.querySelectorAll('.atr-crosshair-line');
|
||||||
|
existingAtrLines.forEach(line => line.remove());
|
||||||
|
const existingMacdLines = document.querySelectorAll('.macd-crosshair-line');
|
||||||
|
existingMacdLines.forEach(line => line.remove());
|
||||||
|
const existingChanMacdLines = document.querySelectorAll('.chanmacd-crosshair-line');
|
||||||
|
existingChanMacdLines.forEach(line => line.remove());
|
||||||
|
} catch (e) {
|
||||||
|
console.debug('清除十字线时出错:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param.time && param.point) {
|
||||||
|
const timeStr = param.time;
|
||||||
|
const markers = [...buyMarkers, ...sellMarkers].filter(m => m.time === timeStr);
|
||||||
|
|
||||||
|
// 同时检查分型标记
|
||||||
|
const fxMarkers = (window.fxMarkers || []).filter(m => m.time === timeStr);
|
||||||
|
const allMarkers = [...markers, ...fxMarkers];
|
||||||
|
|
||||||
|
// 显示时区调试信息
|
||||||
|
if (window.debugMode) {
|
||||||
|
const timezone = $('#timezone').val();
|
||||||
|
const formattedTime = formatTimeWithTimezone(timeStr * 1000, timezone);
|
||||||
|
|
||||||
|
// 获取当前价格 - 通过param.seriesPrices获取
|
||||||
|
let priceInfo = '';
|
||||||
|
if (param.seriesPrices && param.seriesPrices.size > 0) {
|
||||||
|
// 依次从当前可能的主系列中获取价格
|
||||||
|
if (tvWidget.series.candleSeries && param.seriesPrices.get(tvWidget.series.candleSeries)) {
|
||||||
|
const price = param.seriesPrices.get(tvWidget.series.candleSeries);
|
||||||
|
priceInfo = `价格: ${price.toFixed(2)}`;
|
||||||
|
} else if (tvWidget.series.renkoSeries && param.seriesPrices.get(tvWidget.series.renkoSeries)) {
|
||||||
|
const price = param.seriesPrices.get(tvWidget.series.renkoSeries);
|
||||||
|
priceInfo = `价格: ${price.toFixed(2)}`;
|
||||||
|
} else if (tvWidget.series.heikinSeries && param.seriesPrices.get(tvWidget.series.heikinSeries)) {
|
||||||
|
const price = param.seriesPrices.get(tvWidget.series.heikinSeries);
|
||||||
|
priceInfo = `价格: ${price.toFixed(2)}`;
|
||||||
|
} else if (tvWidget.series.barSeries && param.seriesPrices.get(tvWidget.series.barSeries)) {
|
||||||
|
const price = param.seriesPrices.get(tvWidget.series.barSeries);
|
||||||
|
priceInfo = `价格: ${price.toFixed(2)}`;
|
||||||
|
} else if (tvWidget.series.lineSeries && param.seriesPrices.get(tvWidget.series.lineSeries)) {
|
||||||
|
const price = param.seriesPrices.get(tvWidget.series.lineSeries);
|
||||||
|
priceInfo = `价格: ${price.toFixed(2)}`;
|
||||||
|
} else if (tvWidget.series.areaSeries && param.seriesPrices.get(tvWidget.series.areaSeries)) {
|
||||||
|
const price = param.seriesPrices.get(tvWidget.series.areaSeries);
|
||||||
|
priceInfo = `价格: ${price.toFixed(2)}`;
|
||||||
|
} else if (tvWidget.series.baselineSeries && param.seriesPrices.get(tvWidget.series.baselineSeries)) {
|
||||||
|
const price = param.seriesPrices.get(tvWidget.series.baselineSeries);
|
||||||
|
priceInfo = `价格: ${price.toFixed(2)}`;
|
||||||
|
}
|
||||||
|
// 如果没有蜡烛图系列价格,尝试从区域图系列获取
|
||||||
|
else if (tvWidget.series.areaSeries && param.seriesPrices.get(tvWidget.series.areaSeries)) {
|
||||||
|
const price = param.seriesPrices.get(tvWidget.series.areaSeries);
|
||||||
|
priceInfo = `价格: ${price.toFixed(2)}`;
|
||||||
|
}
|
||||||
|
// 如果没有蜡烛图系列价格,尝试从基线图系列获取
|
||||||
|
else if (tvWidget.series.baselineSeries && param.seriesPrices.get(tvWidget.series.baselineSeries)) {
|
||||||
|
const price = param.seriesPrices.get(tvWidget.series.baselineSeries);
|
||||||
|
priceInfo = `价格: ${price.toFixed(2)}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 仅记录最简短的调试信息
|
||||||
|
console.debug(`十字线: ${timeStr} -> ${formattedTime} (${timezone})`);
|
||||||
|
|
||||||
|
// 显示自定义时区工具提示,包含价格信息
|
||||||
|
crosshairTooltip.innerHTML = `<div style="font-weight:bold">时间: ${formattedTime}</div>` +
|
||||||
|
(priceInfo ? `<div>${priceInfo}</div>` : '');
|
||||||
|
crosshairTooltip.style.display = 'block';
|
||||||
|
crosshairTooltip.style.left = (param.point.x + 15) + 'px';
|
||||||
|
crosshairTooltip.style.top = (param.point.y - 30) + 'px';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allMarkers.length > 0) {
|
||||||
|
// 有买卖点或分型标记,显示自定义提示
|
||||||
|
const tooltips = allMarkers.map(m => m.tooltip).join('<br><hr style="margin: 5px 0;">');
|
||||||
|
tooltipElement.innerHTML = tooltips;
|
||||||
|
tooltipElement.style.display = 'block';
|
||||||
|
tooltipElement.style.left = (param.point.x + 15) + 'px';
|
||||||
|
tooltipElement.style.top = (param.point.y + 15) + 'px';
|
||||||
|
} else {
|
||||||
|
// 隐藏提示
|
||||||
|
tooltipElement.style.display = 'none';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 隐藏提示
|
||||||
|
tooltipElement.style.display = 'none';
|
||||||
|
crosshairTooltip.style.display = 'none';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 处理图表缩放、平移等事件,隐藏提示
|
||||||
|
mainChart.timeScale().subscribeVisibleTimeRangeChange(() => {
|
||||||
|
tooltipElement.style.display = 'none';
|
||||||
|
crosshairTooltip.style.display = 'none';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 辅助函数:使用指定时区格式化时间戳
|
// 辅助函数:使用指定时区格式化时间戳
|
||||||
function formatTimeWithTimezone(timestamp, timezone) {
|
function formatTimeWithTimezone(timestamp, timezone) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user