网站首页 > 基础教程 正文
<script>
const EXCHANGE_MAP = {
'SHFE': 113,
'DCE': 114,
'CZCE': 115,
'GFEX': 225,
'INE': 142,
'CFFEX': 220
};
async function fetchVarieties() {
try {
const response = await fetch('https://q.xxx.biz/');
const data = await response.json();
const groupedData = {};
data.list.forEach(item => {
const [exchange, code] = item.uid.split('|');
const variety = code.replace(/\d+/g, '');
if (!groupedData[exchange]) {
groupedData[exchange] = new Set();
}
groupedData[exchange].add({
code: variety,
name: item.name.replace(/\d+/g, '')
});
});
const select = document.getElementById('varietySelect');
Object.entries(groupedData).forEach(([exchange, varieties]) => {
const optgroup = document.createElement('optgroup');
optgroup.label = exchange;
varieties.forEach(variety => {
const option = document.createElement('option');
option.value = `${EXCHANGE_MAP[exchange]}_${variety.code}`;
option.textContent = variety.name;
optgroup.appendChild(option);
});
select.appendChild(optgroup);
});
} catch (error) {
console.error('Error fetching varieties:', error);
}
}
async function fetchContracts(variety) {
try {
const response = await fetch(`https://q.xxx.ink/redis?msgid=${variety}`);
const data = await response.json();
return data
.filter(item => /\d+/.test(item.code))
.map(item => `${item.mktid}_${item.code}`);
} catch (error) {
console.error('Error fetching contracts:', error);
return [];
}
}
async function fetchPrices(contracts) {
try {
console.log('Fetching prices for contracts:', contracts);
const response = await fetch(`https://q.xxx.ink/custom/${contracts.join(',')}?orderBy=code&sort=asc&pageSize=100&pageIndex=0&callbackName=`);
const text = await response.text();
console.log('Raw response:', text);
const jsonStr = text.replace(/^[^({]*\(|\)[^}]*$/g, '');
console.log('Processed JSON string:', jsonStr);
try {
const data = JSON.parse(jsonStr);
console.log('Parsed data:', data);
if (data && Array.isArray(data.list)) {
return data.list;
}
return [];
} catch (parseError) {
console.error('Error parsing JSON:', parseError);
console.log('Problematic JSON string:', jsonStr);
return [];
}
} catch (error) {
console.error('Error fetching prices:', error);
return [];
}
}
function updatePriceTable(prices) {
const tbody = document.querySelector('#priceData tbody');
tbody.innerHTML = '';
if (!Array.isArray(prices) || prices.length === 0) {
const row = document.createElement('tr');
row.innerHTML = '<td colspan="4" style="text-align: center;">暂无数据</td>';
tbody.appendChild(row);
return;
}
prices.forEach(item => {
const row = document.createElement('tr');
row.innerHTML = `
<td>${item.name || '-'}</td>
<td>${item.p || '-'}</td>
<td>${item.zdf || '-'}%</td>
<td>${item.vol || 0}</td>
<td>${item.ccl || 0}</td>
`;
tbody.appendChild(row);
});
}
function sortContracts(prices) {
return prices.sort((a, b) => {
const monthA = a.name.match(/\d+/)[0];
const monthB = b.name.match(/\d+/)[0];
return monthA - monthB;
});
}
function updateChart(prices) {
const chartDom = document.getElementById('chartContainer');
const myChart = echarts.init(chartDom);
const sortedPrices = sortContracts(prices);
const option = {
title: {
text: '月间合约对比',
left: 'center'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
}
},
legend: {
data: ['价格', '成交量', '持仓量'],
top: 30,
left: 'center'
},
grid: [{
left: '3%',
right: '3%',
height: '50%'
}, {
left: '3%',
right: '3%',
top: '65%',
height: '25%'
}],
xAxis: [{
type: 'category',
data: sortedPrices.map(item => item.name),
axisLine: { onZero: true },
grid: { top: '50%' }
}, {
type: 'category',
gridIndex: 1,
data: sortedPrices.map(item => item.name),
position: 'bottom'
}],
yAxis: [{
name: '价格',
type: 'value',
splitLine: {
show: true
},
min: function (value) {
return value.min * 0.99; // 设置 Y 轴最小值为数据最小值的 0.9 倍
},
max: function (value) {
return value.max * 1.01; // 设置 Y 轴最大值为数据最大值的 1.1 倍
}
}, {
gridIndex: 1,
name: '成交量/持仓量',
type: 'value',
splitLine: {
show: true
},
min: function (value) {
return value.min * 0.99; // 设置 Y 轴最小值为数据最小值的 0.9 倍
},
max: function (value) {
return value.max * 1.01; // 设置 Y 轴最大值为数据最大值的 1.1 倍
}
}],
series: [{
name: '价格',
type: 'line',
data: sortedPrices.map(item => item.p || 0),
smooth: true,
lineStyle: {
width: 2
},
itemStyle: {
color: '#5470c6'
}
}, {
name: '成交量',
type: 'bar',
xAxisIndex: 1,
yAxisIndex: 1,
data: sortedPrices.map(item => item.vol || 0),
itemStyle: {
color: '#91cc75'
}
}, {
name: '持仓量',
type: 'bar',
xAxisIndex: 1,
yAxisIndex: 1,
data: sortedPrices.map(item => item.ccl || 0),
itemStyle: {
color: '#fac858'
}
}],
dataZoom: [{
type: 'inside',
xAxisIndex: [0, 1],
start: 0,
end: 100
}, {
show: true,
xAxisIndex: [0, 1],
type: 'slider',
bottom: 10,
start: 0,
end: 100
}]
};
myChart.setOption(option);
window.addEventListener('resize', () => {
myChart.resize();
});
}
document.getElementById('varietySelect').addEventListener('change', async (e) => {
const variety = e.target.value;
if (!variety) {
document.getElementById('contractList').textContent = '';
updatePriceTable([]);
const chartDom = document.getElementById('chartContainer');
const myChart = echarts.init(chartDom);
myChart.clear();
return;
}
document.querySelector('.loading').style.display = 'block';
try {
const contracts = await fetchContracts(variety);
document.getElementById('contractList').textContent =
`[${contracts.map(c => c.split('_')[1]).join(',')}]`;
const prices = await fetchPrices(contracts);
updatePriceTable(prices);
if (prices && prices.length > 0) {
updateChart(prices);
}
} catch (error) {
console.error('Error updating data:', error);
document.getElementById('contractList').textContent = '获取数据失败';
updatePriceTable([]);
} finally {
document.querySelector('.loading').style.display = 'none';
}
});
// 从URL中获取默认品种
(async function() {
const urlParams = new URLSearchParams(window.location.search);
const defaultVariety = urlParams.get('variety');
if (defaultVariety) {
document.getElementById('varietySelect').value = defaultVariety;
await fetchContracts(defaultVariety);
const contracts = await fetchContracts(defaultVariety);
document.getElementById('contractList').textContent =
`[${contracts.map(c => c.split('_')[1]).join(',')}]`;
const prices = await fetchPrices(contracts);
updatePriceTable(prices);
if (prices && prices.length > 0) {
updateChart(prices);
}
} else {
await fetchVarieties();
}
})();
</script>
这段代码涉及到了很多JavaScript的知识点,以下是一些主要的知识点:
1. 变量和常量
●使用const声明常量,例如EXCHANGE_MAP。
●变量的解构赋值,如const [exchange, code] = item.uid.split('|');。
2. 数据结构
●使用对象({})和Map进行数据存储和检索。
●使用Set来存储唯一值。
3. 异步编程
●使用async/await进行异步操作,简化Promise的使用。
●使用fetchAPI进行网络请求。
4. 数组和字符串方法
●数组的forEach、map、filter等方法。
●字符串的split、replace、match等方法。
5. DOM操作
●使用document.getElementById、document.createElement等方法操作DOM。
●使用appendChild方法添加子元素。
6. 事件处理
●使用addEventListener为DOM元素添加事件监听器。
7. 错误处理
●使用try...catch语句进行错误捕获和处理。
8. JSON处理
●使用JSON.parse解析JSON字符串。
●处理JSON解析错误。
9. 正则表达式
●使用正则表达式进行字符串匹配和替换,如/\d+/g。
10. 排序
●使用数组的sort方法进行排序。
11. ECharts库
●使用ECharts库进行数据可视化,包括图表的配置和更新。
12. 模块化
●代码结构体现了模块化的思想,将不同的功能封装在不同的函数中。
13. 立即执行函数表达式(IIFE)
●使用IIFE来封装一些初始化代码,避免污染全局作用域。
14. URL和查询参数处理
●使用URLSearchParams处理URL查询参数。
15. 条件渲染
●根据数据是否存在来决定渲染内容,例如在没有数据时显示“暂无数据”。
这些知识点覆盖了JavaScript的基础语法、异步编程、DOM操作、数据处理和可视化等多个方面,展示了现代JavaScript开发的综合应用。
- 上一篇: JavaScript实现的9大排序算法
- 下一篇: 【JS逆向百例】某点数据逆向分析,多方法详解
猜你喜欢
- 2024-12-14 js数组方法笔记
- 2024-12-14 Cash:Javascript打造的Unix Shell
- 2024-12-14 如何找出爬取网站的来源IP?
- 2024-12-14 js-ES6 完全使用手册
- 2024-12-14 开发技巧汇总|对于imag.js你不知道的事
- 2024-12-14 JS基本数据类型BigInt
- 2024-12-14 JavaScript数组用法
- 2024-12-14 简单几步让你的 JS 写得更漂亮
- 2024-12-14 第29节 原型prototype-Javascript-零点程序员-王唯
- 2024-12-14 五十四、最基础的冒泡排序
- 最近发表
- 标签列表
-
- gitpush (61)
- pythonif (68)
- location.href (57)
- tail-f (57)
- pythonifelse (59)
- deletesql (62)
- c++模板 (62)
- css3动画 (57)
- c#event (59)
- linuxgzip (68)
- 字符串连接 (73)
- nginx配置文件详解 (61)
- html标签 (69)
- c++初始化列表 (64)
- exec命令 (59)
- canvasfilltext (58)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- node教程 (59)
- console.table (62)
- c++time_t (58)
- phpcookie (58)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)