Browse Source

股票代码数据获取模块添加表格弹窗提示

master^2
王妍洁 3 weeks ago
parent
commit
983128976f
  1. 35520
      data/Stock_5min_A股.csv
  2. 23
      webui/app.py
  3. 487
      webui/templates/index.html

35520
data/Stock_5min_A股.csv
File diff suppressed because it is too large
View File

23
webui/app.py

@ -543,7 +543,7 @@ def create_prediction_chart(df, pred_df, lookback, pred_len, actual_df=None, his
return error_fig.to_json()
# 计算指标
# 计算技术指标
def calculate_indicators(df):
indicators = {}
@ -584,21 +584,16 @@ def calculate_indicators(df):
indicators['rwms_signal'] = (df['close'] > indicators['rwms_mean']).astype(int)
# 三重指数平均(TRIX)策略
# 计算收盘价的EMA
ema1 = df['close'].ewm(span=12, adjust=False).mean()
# 计算EMA的EMA
ema2 = ema1.ewm(span=12, adjust=False).mean()
# 计算EMA的EMA的EMA
ema3 = ema2.ewm(span=12, adjust=False).mean()
# 计算TRIX
indicators['trix'] = (ema3 - ema3.shift(1)) / ema3.shift(1) * 100
# 计算信号线
indicators['trix_signal'] = indicators['trix'].ewm(span=9, adjust=False).mean()
return indicators
# 创建图表
# 技术指标图表绘制
def create_technical_chart(df, pred_df, lookback, pred_len, diagram_type, actual_df=None, historical_start_idx=0):
print(f" 🔍 数据内容: {len(df) if df is not None else 0} 行")
print(f" 🔍 图表类型: {diagram_type}")
@ -703,7 +698,6 @@ def create_technical_chart(df, pred_df, lookback, pred_len, diagram_type, actual
marker_color = '#42A5F5'
))
# 零轴线
fig.add_hline(y = 0, line_dash = "dash", line_color = "gray")
fig.update_layout(yaxis_title = 'MACD')
@ -717,7 +711,6 @@ def create_technical_chart(df, pred_df, lookback, pred_len, diagram_type, actual
line = dict(color = '#26A69A', width = 1)
))
# 超买超卖线
fig.add_hline(y = 70, line_dash = "dash", line_color = "red", name = 'Overbought')
fig.add_hline(y = 30, line_dash = "dash", line_color = "green", name = 'Oversold')
fig.update_layout(yaxis_title = 'RSI', yaxis_range = [0, 100])
@ -848,7 +841,7 @@ def create_technical_chart(df, pred_df, lookback, pred_len, diagram_type, actual
# 布局设置
fig.update_layout(
title = f'{diagram_type} - Technical Indicator (Real Data Only)',
title = f'{diagram_type} - Technical Indicator',
xaxis_title = 'Time',
template = 'plotly_white',
height = 400,
@ -1686,20 +1679,19 @@ def get_model_status():
})
# 股票数据获取接口
@app.route('/api/stock-data', methods=['POST'])
def Stock_Data():
try:
data = request.get_json()
stock_code = data.get('stock_code', '').strip()
# 股票代码不能为空
if not stock_code:
return jsonify({
'success': False,
'error': f'Stock code cannot be empty'
}), 400
# 股票代码格式验证
if not re.match(r'^[a-z]+\.\d+$', stock_code):
return jsonify({
'success': False,
@ -1725,7 +1717,6 @@ def Stock_Data():
adjustflag = "3"
)
# 检查获取结果
if rs.error_code != '0':
bs.logout()
return jsonify({
@ -1733,7 +1724,6 @@ def Stock_Data():
'error': f'Failed to retrieve data, please enter a valid stock code'
}), 400
# 提取数据
data_list = []
while rs.next():
data_list.append(rs.get_row_data())
@ -1744,7 +1734,6 @@ def Stock_Data():
columns = rs.fields
df = pd.DataFrame(data_list, columns=columns)
# 数值列转换
df = df.rename(columns={'time': 'timestamps'})
numeric_columns = ['timestamps','open', 'high', 'low', 'close', 'volume', 'amount']
@ -1753,10 +1742,8 @@ def Stock_Data():
df['timestamps'] = pd.to_datetime(df['timestamps'].astype(str), format='%Y%m%d%H%M%S%f')
# 去除无效数据
df = df.dropna()
# 保存
data_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'data')
os.makedirs(data_dir, exist_ok=True)
@ -1785,6 +1772,7 @@ def Stock_Data():
}), 500
# 技术指标图表绘制接口
@app.route('/api/generate-chart', methods=['POST'])
def generate_chart():
try:
@ -1796,7 +1784,6 @@ def generate_chart():
if field not in data:
return jsonify({'success': False, 'error': f'Missing required field: {field}'}), 400
# 解析参数
file_path = data['file_path']
lookback = int(data['lookback'])
diagram_type = data['diagram_type']

487
webui/templates/index.html

@ -5,7 +5,7 @@
<meta name = "viewport" content = "width = device-width, initial-scale = 1.0">
<title>Kronos Financial Prediction Web UI</title>
{# <script src = "https://cdn.plot.ly/plotly-latest.min.js"></script>#}
<!--? <script src = "https://cdn.plot.ly/plotly-latest.min.js"></script>-->
<script src = "https://cdn.plot.ly/plotly-2.27.0.min.js"></script>
<script src = "https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
@ -157,6 +157,100 @@
background: linear-gradient(135deg, #ffc19d 0%, #ffc19d 100%);
}
/*表格弹窗样式*/
.search {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
}
.search-container{
white-space: nowrap;
padding: 6px 12px;
font-size: 14px;
background-color: #8a94e0;
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
}
.search-modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 1000;
justify-content: center;
align-items: center;
}
.search-modal-content {
background: white;
padding: 20px;
border-radius: 10px;
width: 90%;
max-width: 1000px;
max-height: 80vh;
display: flex;
flex-direction: column;
text-align: center;
}
.search-modal-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
}
.search-modal-title {
margin: 0;
font-size: 1.5rem;
}
.close-modal-btn {
background: #764ba2;
color: white;
border: none;
padding: 5px 10px;
border-radius: 5px;
cursor: pointer;
font-size: 1rem;
}
.search-results-container {
overflow-y: auto;
flex-grow: 1;
}
.rep-code {
cursor: pointer;
padding: 2px 8px;
background: #f5f7fa;
border-radius: 4px;
font-size: 12px;
color: #1989fa;
transition: background 0.2s;
display: inline-block;
text-align: center;
}
.rep-code:hover {
background: #e8f3ff;
}
.representative-codes {
display: flex;
flex-wrap: wrap;
gap: 6px;
justify-content: center;
}
.chart-grid {
display: grid;
grid-template-columns: 1fr auto;
@ -525,9 +619,15 @@
<hr style = "margin: 20px 0; border: 1px solid #e2e8f0;">
<!-- Stock data acquisition -->
<!-- 股票数据采集 -->
<div class = "form-group">
<label class = "sr-only" for = "stock_code">Ticker Symbol Input:</label>
<div class="search">
<label class="sr-only" for="stock_code">Ticker Symbol Input:</label>
<button id="search-btn" class="search-container">
🔍 Search
</button>
</div>
<input type = "text" class = "form-control" id = "stock_code" name = 'stock_code'
value = "{{ stock_code }}" placeholder = "例如:sh.600000" >
@ -539,6 +639,267 @@
📄 Stock Data
</button>
<!--股票数据提示弹窗-->
<div id="search-modal" class="search-modal">
<div class="search-modal-content">
<div class="search-modal-header">
<h3 class="search-modal-title">📃 Stock Code Prompt:</h3>
<button id="close-modal" class="close-modal-btn">×</button>
</div>
<div class="search-results-container">
<table class="comparison-table">
<thead>
<tr>
<th>Exchange</th>
<th>Prefix</th>
<th>Code_Range</th>
<th>Representative_Code</th>
</tr>
</thead>
<tbody id="search-results-body">
<!-- 上海证券交易所 (SSE)-->
<tr>
<td rowspan="5">上海证券交易所 (SSE)</td>
<td rowspan="5">sh.</td>
<td>600</td>
<td class="representative-codes">
<span class="rep-code">sh.600000(浦发银行)</span>
<span class="rep-code">sh.600036(招商银行)</span>
<span class="rep-code">sh.600519(贵州茅台)</span>
<span class="rep-code">sh.600887(伊利股份)</span>
<span class="rep-code">sh.600900(长江电力)</span>
<span class="rep-code">sh.600030(中信证券)</span>
<span class="rep-code">sh.600050(中国联通)</span>
<span class="rep-code">sh.600690(海尔智家)</span>
<span class="rep-code">sh.600570(恒生电子)</span>
<span class="rep-code">sh.600588(用友网络)</span>
</td>
</tr>
<tr>
<td>601</td>
<td class="representative-codes">
<span class="rep-code">sh.601318(中国平安)</span>
<span class="rep-code">sh.601398(工商银行)</span>
<span class="rep-code">sh.601888(中国中免)</span>
<span class="rep-code">sh.601857(中国石油)</span>
<span class="rep-code">sh.601012(隆基绿能)</span>
<span class="rep-code">sh.601988(中国国航)</span>
<span class="rep-code">sh.601088(中国神华)</span>
<span class="rep-code">sh.601766(中国中车)</span>
<span class="rep-code">sh.601390(中国中铁)</span>
<span class="rep-code">sh.601186(中国铁建)</span>
</td>
</tr>
<tr>
<td>603</td>
<td class="representative-codes">
<span class="rep-code">sh.603288(海天味业)</span>
<span class="rep-code">sh.603259(药明康德)</span>
<span class="rep-code">sh.603986(兆易创新)</span>
<span class="rep-code">sh.603501(韦尔股份)</span>
<span class="rep-code">sh.603993(中科曙光)</span>
<span class="rep-code">sh.603899(晨光股份)</span>
<span class="rep-code">sh.603605(珀莱雅)</span>
<span class="rep-code">sh.603707(健友股份)</span>
<span class="rep-code">sh.603833(欧派家居)</span>
<span class="rep-code">sh.603806(福斯特)</span>
</td>
</tr>
<tr>
<td>605</td>
<td class="representative-codes">
<span class="rep-code">sh.605499(东鹏饮料)</span>
<span class="rep-code">sh.605338(巴比食品)</span>
<span class="rep-code">sh.605111(新洁能)</span>
<span class="rep-code">sh.605589(圣泉集团)</span>
<span class="rep-code">sh.605168(三人行)</span>
<span class="rep-code">sh.605066(天正电气)</span>
<span class="rep-code">sh.605155(西大门)</span>
<span class="rep-code">sh.605136(丽人丽妆)</span>
<span class="rep-code">sh.605333(沪光股份)</span>
<span class="rep-code">sh.605358(立昂微)</span>
</td>
</tr>
<tr>
<td>688</td>
<td class="representative-codes">
<span class="rep-code">sh.688012(中微公司)</span>
<span class="rep-code">sh.688981(中芯国际)</span>
<span class="rep-code">sh.688111(金山办公)</span>
<span class="rep-code">sh.688036(传音控股)</span>
<span class="rep-code">sh.688008(澜起科技)</span>
<span class="rep-code">sh.688235(百济神州)</span>
<span class="rep-code">sh.688185(康希诺)</span>
<span class="rep-code">sh.688036(传音控股)</span>
<span class="rep-code">sh.688187(时代电气)</span>
<span class="rep-code">sh.688390(固德威)</span>
</td>
</tr>
<!-- 深圳证券交易所 (SZSE)-->
<tr>
<td rowspan="5">深圳证券交易所</td>
<td rowspan="5">sz.</td>
<td>000</td>
<td class="representative-codes">
<span class="rep-code">sz.000001(平安银行)</span>
<span class="rep-code">sz.000002(万科A)</span>
<span class="rep-code">sz.000858(五粮液)</span>
<span class="rep-code">sz.000333(美的集团)</span>
<span class="rep-code">sz.000651(格力电器)</span>
<span class="rep-code">sz.000538(云南白药)</span>
<span class="rep-code">sz.000063(中兴通讯)</span>
<span class="rep-code">sz.000100(TCL科技)</span>
<span class="rep-code">sz.000157(中联重科)</span>
<span class="rep-code">sz.000895(双汇发展)</span>
</td>
</tr>
<tr>
<td>001</td>
<td class="representative-codes">
<span class="rep-code">sz.001203(大中矿业)</span>
<span class="rep-code">sz.001208(华菱线缆)</span>
<span class="rep-code">sz.001212(中旗新材)</span>
<span class="rep-code">sz.001213(中铁特货)</span>
<span class="rep-code">sz.001215(千味央厨)</span>
<span class="rep-code">sz.001217(华尔泰)</span>
<span class="rep-code">sz.001218(丽臣实业)</span>
<span class="rep-code">sz.001222(源飞宠物)</span>
<span class="rep-code">sz.001225(和泰机电)</span>
<span class="rep-code">sz.001309(德明利)</span>
</td>
</tr>
<tr>
<td>002</td>
<td class="representative-codes">
<span class="rep-code">sz.002024(苏宁易购)</span>
<span class="rep-code">sz.002027(分众传媒)</span>
<span class="rep-code">sz.002555(三七互娱)</span>
<span class="rep-code">sz.002624(完美世界)</span>
<span class="rep-code">sz.002049(紫光国微)</span>
<span class="rep-code">sz.002179(中航光电)</span>
<span class="rep-code">sz.002415(海康威视)</span>
<span class="rep-code">sz.002475(立讯精密)</span>
<span class="rep-code">sz.002594(比亚迪)</span>
<span class="rep-code">sz.002142(宁波银行)</span>
</td>
</tr>
<tr>
<td>003</td>
<td class="representative-codes">
<span class="rep-code">sz.003816(中国广核)</span>
<span class="rep-code">sz.003022(联泓新科)</span>
<span class="rep-code">sz.003031(中瓷电子)</span>
<span class="rep-code">sz.003032(传智教育)</span>
<span class="rep-code">sz.003035(南网能源)</span>
<span class="rep-code">sz.003036(泰坦股份)</span>
<span class="rep-code">sz.003000(劲仔食品)</span>
<span class="rep-code">sz.003001(中晶科技)</span>
<span class="rep-code">sz.003002(传智教育)</span>
<span class="rep-code">sz.003011(海象新材)</span>
</td>
</tr>
<tr>
<td>300</td>
<td class="representative-codes">
<span class="rep-code">sz.300750(宁德时代)</span>
<span class="rep-code">sz.300059(东方财富)</span>
<span class="rep-code">sz.300124(汇川技术)</span>
<span class="rep-code">sz.300760(迈瑞医疗)</span>
<span class="rep-code">sz.300014(亿纬锂能)</span>
<span class="rep-code">sz.300122(智飞生物)</span>
<span class="rep-code">sz.300015(爱尔眼科)</span>
<span class="rep-code">sz.300274(阳光电源)</span>
<span class="rep-code">sz.300496(中科创达)</span>
<span class="rep-code">sz.300782(卓胜微)</span>
</td>
</tr>
<!--? 北京证券交易所 (BSE) -->
<!--? <tr>-->
<!--? <td rowspan="5">北京证券交易所 (BSE)</td>-->
<!--? <td rowspan="5">bj.</td>-->
<!--? <td>43</td>-->
<!--? <td class="representative-codes">-->
<!--? <span class="rep-code">bj.430047(诺思兰德)</span>-->
<!--? <span class="rep-code">bj.430090(同辉信息)</span>-->
<!--? <span class="rep-code">bj.430198(微创光电)</span>-->
<!--? <span class="rep-code">bj.430300(辰光医疗)</span>-->
<!--? <span class="rep-code">bj.430425(乐创技术)</span>-->
<!--? <span class="rep-code">bj.430476(海能技术)</span>-->
<!--? <span class="rep-code">bj.430510(丰光精密)</span>-->
<!--? <span class="rep-code">bj.430556(雅葆轩)</span>-->
<!--? <span class="rep-code">bj.430564(天润科技)</span>-->
<!--? <span class="rep-code">bj.430685(新芝生物)</span>-->
<!--? </td>-->
<!--? </tr>-->
<!--? <tr>-->
<!--? <td>83</td>-->
<!--? <td class="representative-codes">-->
<!--? <span class="rep-code">bj.830799(艾融软件)</span>-->
<!--? <span class="rep-code">bj.830809(安达科技)</span>-->
<!--? <span class="rep-code">bj.830839(万通液压)</span>-->
<!--? <span class="rep-code">bj.830866(齐鲁华信)</span>-->
<!--? <span class="rep-code">bj.830879(基康仪器)</span>-->
<!--? <span class="rep-code">bj.830896(旺成科技)</span>-->
<!--? <span class="rep-code">bj.830946(森萱医药)</span>-->
<!--? <span class="rep-code">bj.830964(润农节水)</span>-->
<!--? <span class="rep-code">bj.831010(凯添燃气)</span>-->
<!--? <span class="rep-code">bj.831039(国义招标)</span>-->
<!--? </td>-->
<!--? </tr>-->
<!--? <tr>-->
<!--? <td>87</td>-->
<!--? <td class="representative-codes">-->
<!--? <span class="rep-code">bj.870204(沪江材料)</span>-->
<!--? <span class="rep-code">bj.870357(雅葆轩)</span>-->
<!--? <span class="rep-code">bj.870436(大地电气)</span>-->
<!--? <span class="rep-code">bj.870640(曙光数创)</span>-->
<!--? <span class="rep-code">bj.870726(鸿智科技)</span>-->
<!--? <span class="rep-code">bj.870866(视声智能)</span>-->
<!--? <span class="rep-code">bj.870976(视声智能)</span>-->
<!--? <span class="rep-code">bj.871263(一致魔芋)</span>-->
<!--? <span class="rep-code">bj.871396(佳合科技)</span>-->
<!--? <span class="rep-code">bj.871478(海泰新能)</span>-->
<!--? </td>-->
<!--? </tr>-->
<!--? <tr>-->
<!--? <td>89</td>-->
<!--? <td class="representative-codes">-->
<!--? <span class="rep-code">bj.892089(科强股份)</span>-->
<!--? <span class="rep-code">bj.892282(美心翼申)</span>-->
<!--? <span class="rep-code">bj.892358(派诺科技)</span>-->
<!--? <span class="rep-code">bj.892519(捷众科技)</span>-->
<!--? <span class="rep-code">bj.892541(康农种业)</span>-->
<!--? <span class="rep-code">bj.892622(许昌智能)</span>-->
<!--? <span class="rep-code">bj.892679(云星宇)</span>-->
<!--? <span class="rep-code">bj.892748(欣捷高新)</span>-->
<!--? <span class="rep-code">bj.892810(捷安高科)</span>-->
<!--? <span class="rep-code">bj.892925(海昇药业)</span>-->
<!--? </td>-->
<!--? </tr>-->
<!--? <tr>-->
<!--? <td>920</td>-->
<!--? <td class="representative-codes">-->
<!--? <span class="rep-code">bj.920099(万达轴承)</span>-->
<!--? <span class="rep-code">bj.920175(欧福蛋业)</span>-->
<!--? <span class="rep-code">bj.920177(瑞华技术)</span>-->
<!--? <span class="rep-code">bj.920179(和特能源)</span>-->
<!--? <span class="rep-code">bj.920180(豪钢重工)</span>-->
<!--? <span class="rep-code">bj.920179(和特能源)</span>-->
<!--? </td>-->
<!--? </tr>-->
</tbody>
</table>
</div>
</div>
</div>
<hr style="margin: 20px 0; border: 1px solid #e2e8f0;">
@ -702,6 +1063,7 @@
<br>
<!--技术指标图表-->
<h2>📶 Technical Indicator Chart</h2>
<div id="indicator-status" class="indicator-status" style="display: none;"></div>
@ -717,7 +1079,7 @@
<option value="Bollinger Bands (BB)">Bollinger Bands (BB)</option>
<option value="Stochastic Oscillator (STOCH)">Stochastic Oscillator (STOCH)</option>
<option value="Rolling Window Mean Strategy">Rolling Window Mean Strategy</option>
<option value="TRIX Indicator (TRIX)">Triple Exponential Average (TRIX) Strategy</option>
<option value="TRIX Indicator (TRIX)">TRIX Indicator (TRIX)</option>
</select>
<button id="generate-chart-btn" class="btn btn-warning">
@ -735,7 +1097,7 @@
<div id="indicator-chart"></div>
<!-- Data Presentation -->
<!-- 数据表格 -->
<div id="data-presentation" class="comparison-section" style="display: none;">
<h3>💹 Financial Data Visualization</h3>
@ -908,54 +1270,79 @@
//Stock Data按钮
document.addEventListener('DOMContentLoaded', function() {
const generateChartBtn = document.getElementById('stock-data-btn');
if (generateChartBtn) {
generateChartBtn.addEventListener('click', StockData);
console.log('Stock Data button event listener bound');
} else {
console.error('stock-data-btn element not found');
}
});
const generateChartBtn = document.getElementById('stock-data-btn');
if (generateChartBtn) {
generateChartBtn.addEventListener('click', StockData);
console.log('Stock Data button event listener bound');
} else {
console.error('stock-data-btn element not found');
}
});
async function StockData() {
console.log('Get stock data...');
const stockCodeInput = document.getElementById('stock_code');
const generateBtn = document.getElementById('stock-data-btn');
const stockCode = stockCodeInput.value.trim();
generateBtn.disabled = true;
try {
if (!stockCode) {
showStatus('error', 'Stock code cannot be empty');
return;
}
console.log('Get stock data...');
const stockCodeInput = document.getElementById('stock_code');
const generateBtn = document.getElementById('stock-data-btn');
const stockCode = stockCodeInput.value.trim();
generateBtn.disabled = true;
try {
if (!stockCode) {
showStatus('error', 'Stock code cannot be empty');
return;
}
const stockCodeRegex = /^[a-z]+\.\d+$/;
if (!stockCodeRegex.test(stockCode)) {
showStatus('error', 'The ticker symbol is in the wrong format');
return;
}
const stockCodeRegex = /^[a-z]+\.\d+$/;
if (!stockCodeRegex.test(stockCode)) {
showStatus('error', 'The ticker symbol is in the wrong format');
return;
}
showLoading(true);
const response = await axios.post('/api/stock-data', {stock_code: stockCode});
if (response.data.success) {
showStatus('success', `Successfully fetched data for ${stockCode}`);
loadDataFiles();
stockCodeInput.value = '';
} else {
showStatus('error', response.data.error || 'Failed to fetch stock data');
}
} catch (error) {
console.error('❌ Failed to fetch stock data:', error);
showStatus('error', `Failed to fetch data`);
} finally {
showLoading(false);
if (generateBtn) generateBtn.disabled = false;
}
}
showLoading(true);
const response = await axios.post('/api/stock-data', {stock_code: stockCode});
// Search按钮表格弹窗
document.addEventListener('DOMContentLoaded', function() {
const searchBtn = document.getElementById('search-btn');
const searchModal = document.getElementById('search-modal');
const closeModal = document.getElementById('close-modal');
const stockCodeInput = document.getElementById('stock_code');
if (response.data.success) {
showStatus('success', `Successfully fetched data for ${stockCode}`);
loadDataFiles();
stockCodeInput.value = '';
} else {
showStatus('error', response.data.error || 'Failed to fetch stock data');
}
} catch (error) {
console.error('❌ Failed to fetch stock data:', error);
showStatus('error', `Failed to fetch data`);
} finally {
showLoading(false);
if (generateBtn) generateBtn.disabled = false;
}
searchBtn.addEventListener('click', () => {
searchModal.style.display = 'flex';
});
closeModal.addEventListener('click', () => {
searchModal.style.display = 'none';
});
document.addEventListener('click', (e) => {
if (e.target.classList.contains('rep-code')) {
const code = e.target.textContent.match(/[a-z]+\.\d+/)[0];
stockCodeInput.value = code;
closeModalFunc();
}
});
});
// Load data file list
@ -1262,7 +1649,7 @@
});
// Generate technical chart
// 技术指标图表
async function generateTechnicalChart() {
console.log('Generating technical indicator chart...');
@ -1275,7 +1662,6 @@
try {
await new Promise(resolve => setTimeout(resolve, 2000));
// get arguments
const startHandle = document.getElementById('start-handle');
const endHandle = document.getElementById('end-handle');
@ -1292,11 +1678,10 @@
const filePath = document.getElementById('data-file-select').value;
const diagramType = document.getElementById('diagram_type').value;
// validate arguments
if (!filePath) throw new Error('Please select a data file first');
if (isNaN(lookback) || isNaN(predLen)) throw new Error('Invalid parameters');
// fetch chart data
// 获取接口
const response = await fetch('/api/generate-chart', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
@ -1312,7 +1697,7 @@
const result = await response.json();
if (!result.success) throw new Error(result.error || 'Failed to generate chart');
// render the chart
// 渲染图标
const chartContainer = document.getElementById('indicator-chart');
if (chartContainer) {
if (chartContainer.data) Plotly.purge(chartContainer);
@ -1347,7 +1732,7 @@
}
// Fill data table
// 数据表格
function fillDataTable(data) {
const tbody = document.getElementById('data-tbody');

Loading…
Cancel
Save