网站首页 > 技术文章 正文
<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开发的综合应用。
- 上一篇: js基础学习
- 下一篇: 肝一下Go.js的高级使用—动态显示效果......
猜你喜欢
- 2025-01-02 JavaScript字符串toString()方法教程
- 2025-01-02 vue3 - 内置组件Teleport的使用
- 2025-01-02 网页三维CAD中加载和保存STEP模型
- 2025-01-02 在.NET Web API中设置响应输出Json数据格式的两种常用方式
- 2025-01-02 剖析Selenium代码执行时元素查找失败的缘由
- 2025-01-02 H5的Canvas绘图——使用fabricjs绘制一个可多选的随机9宫格
- 2025-01-02 jscanify:支持 Node.js/浏览器/React 移动文档扫描仪
- 2025-01-02 js事件机制详解
- 2025-01-02 Java ArrayList用法详解附代码示例
- 2025-01-02 如何用枚举快速提高编程效率,数据元素快速对应,小枚举大作用
- 05-16在实际操作过程中如何避免出现SQL注入漏洞
- 05-16MySQL中 in数量限制
- 05-16一文讲懂SQL筛选子句HAVING子句
- 05-16性能调优实战:Spring Boot 多线程处理SQL IN语句大量值的优化方案
- 05-16sqlserver数据库中的模糊查询like和通配符的使用
- 05-16SQL必备 和 表关联
- 05-16SQL Server优化50法
- 05-16他们一直都在!最新强军大片来了
- 最近发表
- 标签列表
-
- cmd/c (64)
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- sqlset (64)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- chromepost (65)
- c++int转char (75)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- js数组插入 (83)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)