<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="#B4E6FB">
</head>
<style type="text/css">
body { margin: 0; padding: 0; }
.Kline-div {
position: fixed;
width: 100%;
bottom: 0;
top: 0;
}
.Kline-div .K-line {
height: 75%;
width: 100%;
}
.loading {
display: none;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
}
.loading .spinner {
border: 4px solid rgba(255, 255, 255, 0.3);
border-top: 4px solid #13B777;
border-radius: 50%;
width: 40px;
height: 40px;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
<body>
<div id="Kline-div" class="Kline-div">
<div id="m-line" class="m-line"></div>
<div id="k-content" class="K-line"></div>
</div>
<div class="loading">
<div class="spinner"></div>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.js"></script>
<script src="https://cdn.bootcss.com/echarts/3.7.1/echarts.min.js"></script>
<script>
var bgColor = "#121420";
var upColor = "#F9293E";
var downColor = "#00aa3b";
var ma5Color = "#39afe6";
var ma10Color = "#da6ee8";
var ma20Color = "#ffab42";
var ma30Color = "#00940b";
function splitData(rawData) {
var datas = [];
var times = [];
var vols = [];
for (var i = 0; i < rawData.length; i++) {
datas.push(rawData[i]);
times.push(rawData[i].splice(0, 1)[0]);
vols.push(rawData[i][4]);
}
return { datas: datas, times: times, vols: vols };
}
function calculateMA(dayCount, data) {
var result = [];
for (var i = 0, len = data.times.length; i < len; i++) {
if (i < dayCount) {
result.push('-');
continue;
}
var sum = 0;
for (var j = 0; j < dayCount; j++) {
sum += data.datas[i - j][1];
}
result.push((sum / dayCount).toFixed(2));
}
return result;
}
var calcEMA = function (n, data, field) {
var i, l, ema, a;
a = 2 / (n + 1);
if (field) {
ema = [data[0][field]];
for (i = 1, l = data.length; i < l; i++) {
ema.push((a * data[i][field] + (1 - a) * ema[i - 1]).toFixed(2));
}
} else {
ema = [data[0]];
for (i = 1, l = data.length; i < l; i++) {
ema.push((a * data[i] + (1 - a) * ema[i - 1]).toFixed(3));
}
}
return ema;
};
var calcDIF = function (short, long, data, field) {
var i, l, dif, emaShort, emaLong;
dif = [];
emaShort = calcEMA(short, data, field);
emaLong = calcEMA(long, data, field);
for (i = 0, l = data.length; i < l; i++) {
dif.push((emaShort[i] - emaLong[i]).toFixed(3));
}
return dif;
};
var calcDEA = function (mid, dif) {
return calcEMA(mid, dif);
};
var calcMACD = function (short, long, mid, data, field) {
var i, l, dif, dea, macd, result;
result = {};
macd = [];
dif = calcDIF(short, long, data, field);
dea = calcDEA(mid, dif);
for (i = 0, l = data.length; i < l; i++) {
macd.push(((dif[i] - dea[i]) * 2).toFixed(3));
}
result.dif = dif;
result.dea = dea;
result.macd = macd;
return result;
};
function initKOption(cdata) {
var data = splitData(cdata);
var macd = calcMACD(12, 26, 9, data.datas, 1);
var lastDataIndex = data.datas.length - 1;
var lastData = data.datas[lastDataIndex];
return {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
}
},
legend: [
{
icon: 'rect',
type: 'scroll',
itemWidth: 14,
itemHeight: 2,
animation: true,
textStyle: {
fontSize: 12,
color: '#0e99e2'
},
pageIconColor: '#0e99e2',
data: [
{ name: 'MA5', textStyle: { color: '#39afe6' } },
{ name: 'MA10', textStyle: { color: '#da6ee8' } },
{ name: 'MA20', textStyle: { color: '#ffab42' } },
{ name: 'MA30', textStyle: { color: '#00940b' } },
{ name: 'DIF', textStyle: { color: '#39afe6' } },
{ name: 'DEA', textStyle: { color: '#da6ee8' } }
],
top: '-1%',
left: 'center'
},
// {
// icon: 'rect',
// type: 'scroll',
// itemWidth: 14,
// itemHeight: 2,
// animation: true,
// textStyle: {
// fontSize: 12,
// color: '#0e99e2'
// },
// pageIconColor: '#0e99e2',
// data: [
// { name: 'Volumn', textStyle: { color: '#ffab42' } }
// ],
// top: '2%',
// left: 'center'
// },
{
icon: 'rect',
type: 'scroll',
itemWidth: 14,
itemHeight: 2,
animation: true,
textStyle: {
fontSize: 12,
color: '#0e99e2'
},
pageIconColor: '#0e99e2',
data: [
// { name: 'Volumn', textStyle: { color: '#ffab42' } },
// { name: 'MACD', textStyle: { color: '#ffab42' } },
// { name: 'DIF', textStyle: { color: '#39afe6' } },
// { name: 'DEA', textStyle: { color: '#da6ee8' } }
],
top: '4%',
left: 'center'
}
],
axisPointer: {
show: true
},
color: [ma5Color, ma10Color, ma20Color, ma30Color],
grid: [{
id: 'gd1',
left: '1%',
right: '60',
height: '50%',
top: '5%'
}, {
left: '1%',
right: '60',
top: '60%',
height: '15%'
}, {
left: '1%',
right: '60',
top: '80%',
height: '14%'
}],
xAxis: [{
type: 'category',
data: data.times,
scale: true,
boundaryGap: false,
axisLine: {
onZero: false
},
axisLabel: {
show: true,
color: '#9b9da9',
fontSize: 10
},
splitLine: {
show: true,
lineStyle: {
color: '#181a23'
}
},
splitNumber: 20,
min: 'dataMin',
max: 'dataMax'
}, {
type: 'category',
gridIndex: 1,
data: data.times,
axisLabel: {
color: '#9b9da9',
fontSize: 10
},
splitLine: {
show: true,
lineStyle: {
color: '#181a23'
}
},
}, {
type: 'category',
gridIndex: 2,
data: data.times,
axisLabel: {
// 显示第三张图表的x轴时间
show: true,
color: '#9b9da9',
fontSize: 10
},
axisLine: {
show: true,
lineStyle: {
color: '#181a23'
}
},
splitLine: {
// 添加背景网格
show: true,
lineStyle: {
color: '#181a23'
}
}
}],
yAxis: [{
position: 'right', // 从左到右显示刻度
scale: true,
z: 4,
axisLabel: {
color: '#c7c7c7',
inside: false,
position: 'right'
},
splitLine: {
show: true,
lineStyle: {
color: '#181a23'
}
},
}, {
position: 'right', // 从左到右显示刻度
gridIndex: 1,
splitNumber: 3,
z: 4,
axisLine: {
onZero: false
},
axisTick: {
show: false
},
splitLine: {
show: true,
lineStyle: {
color: '#181a23'
}
},
axisLabel: {
color: '#c7c7c7',
inside: false,
fontSize: 8
},
}, {
position: 'right', // 从左到右显示刻度
z: 4,
gridIndex: 2,
splitNumber: 4,
axisLine: {
onZero: false
},
axisTick: {
show: false
},
splitLine: {
// 添加背景网格
show: true,
lineStyle: {
color: '#181a23'
}
},
axisLabel: {
color: '#c7c7c7',
inside: false,
fontSize: 8
},
}],
dataZoom: [{
type: 'inside',
xAxisIndex: [0, 1, 2],
// start: 100,
// end: 10,
throttle: 10,
top: '94%',
height: '6%',
left: '10%',
right: '10%',
borderColor: '#696969',
textStyle: {
color: '#dcdcdc'
},
handleSize: '90%',
handleIcon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
dataBackground: {
lineStyle: {
color: '#fff'
},
areaStyle: {
color: '#696969'
}
}
}],
animation: true,
backgroundColor: bgColor,
blendMode: 'source-over',
series: [{
name: 'Kline',
type: 'candlestick',
data: data.datas,
barWidth: '55%',
large: true,
largeThreshold: 100,
itemStyle: {
normal: {
color: upColor,
color0: downColor,
borderColor: upColor,
borderColor0: downColor,
}
},
markLine: {
symbol: 'none',
data: [
{
name: 'Last Close',
xAxis: data.times[lastDataIndex],
yAxis: lastData[1],
lineStyle: {
type: 'dotted',
color: '#ffab42'
},
label: {
show: true,
// 将数值标签位置改为左边的y轴
formatter: function (params) {
return 'Last Close: ' + params.value.toFixed(2);
},
position: 'insideEndTop',
color: '#ffab42',
fontSize: 12
}
}
]
}
}, {
name: 'MA5',
type: 'line',
data: calculateMA(5, data),
smooth: true,
symbol: "none",
lineStyle: {
normal: {
opacity: 0.8,
color: '#39afe6',
width: 1
}
},
}, {
name: 'MA10',
type: 'line',
data: calculateMA(10, data),
smooth: true,
symbol: "none",
lineStyle: {
normal: {
opacity: 0.8,
color: '#da6ee8',
width: 1
}
}
}, {
name: 'MA20',
type: 'line',
data: calculateMA(20, data),
smooth: true,
symbol: "none",
lineStyle: {
opacity: 0.8,
width: 1,
color: ma20Color
}
}, {
name: 'MA30',
type: 'line',
data: calculateMA(30, data),
smooth: true,
symbol: "none",
lineStyle: {
normal: {
opacity: 0.8,
width: 1,
color: ma30Color
}
}
}, {
name: 'Volumn',
type: 'bar',
xAxisIndex: 1,
yAxisIndex: 1,
data: data.vols,
barWidth: '60%',
itemStyle: {
normal: {
color: function (params) {
var colorList;
if (data.datas[params.dataIndex][1] > data.datas[params.dataIndex][0]) {
colorList = upColor;
} else {
colorList = downColor;
}
return colorList;
},
}
}
}, {
name: 'MACD',
type: 'bar',
xAxisIndex: 2,
yAxisIndex: 2,
data: macd.macd,
barWidth: '40%',
itemStyle: {
normal: {
color: function (params) {
var colorList;
if (params.data >= 0) {
colorList = upColor;
} else {
colorList = downColor;
}
return colorList;
},
}
}
}, {
name: 'DIF',
type: 'line',
symbol: "none",
xAxisIndex: 2,
yAxisIndex: 2,
data: macd.dif,
lineStyle: {
normal: {
color: '#39afe6',
width: 1
}
}
}, {
name: 'DEA',
type: 'line',
symbol: "none",
xAxisIndex: 2,
yAxisIndex: 2,
data: macd.dea,
lineStyle: {
normal: {
opacity: 0.8,
color: '#da6ee8',
width: 1
}
}
}]
};
}
$('.loading').fadeIn();
$('#chart').hide()
// 更新图表数据
function tabChange(tab) {
let newKlineData = []
$.ajax({
url: 'https://api-aws.huobi.pro/market/history/kline',
type: 'GET',
data: {
symbol: 'btcusdt',
period: tab,
size: 70
},
success: function (data) {
// 加载完成后隐藏加载动画
$('.loading').fadeOut();
$('#chart').show()
// 请求成功 data 包含响应数据
if (data.status == 'ok') {
// console.log(data.data)
const res = data.data
for (i = 0; i < res.length; i++) {
const timestamp = res[i].id * 1000; // 转换为毫秒级时间戳
const date = new Date(timestamp);
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
const hours = date.getHours();
const minutes = date.getMinutes();
const seconds = date.getSeconds();
const formattedTime = String(month).padStart(2, '0') + '/' + String(day).padStart(2, '0') + '-' + String(hours).padStart(2, '0') + ':' + String(minutes).padStart(2, '0') ;
//newKlineData.push([formattedTime, res[i].open, res[i].close, '-', '-', res[i].low, res[i].high, res[i].vol, res[i].count,'-'])
newKlineData.push([formattedTime, res[i].open, res[i].close, res[i].low, res[i].high, res[i].vol, res[i].count])
}
// initChart(newKlineData.reverse(),false,line,res[0].close);
fetchDataAndUpdateChart(newKlineData.reverse());
}
},
error: function (jqXHR, textStatus, errorThrown) {
// $('.loading').fadeOut();
// $('#chart').show()
console.log('Error: ' + textStatus);
}
});
}
function fetchDataAndUpdateChart(kdata) {
//[{
// "id": 1716521040,
// "open": 67870.48,
// "close": 67870.49,
// "low": 67870.48,
// "high": 67870.49,
// "amount": 0.005206,
// "vol": 353.33376507,
// "count": 2
//},{
// "id": 1716520980,
// "open": 67850.34,
// "close": 67876.6,
// "low": 67850.34,
// "high": 67876.61,
// "amount": 0.18876069628094272,
// "vol": 12808.80971393,
// "count": 28
//}]
kChart.setOption(initKOption(kdata));
}
var kChart = echarts.init(document.getElementById('k-content'));
window.addEventListener('resize', handleResize);
function handleResize() {
kChart.resize();
}
tabChange('1min'); // 1hou 1day
</script>
</body>
</html>
echarts图表k线行情
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 先上效果图 源码和使用说明已经开源至GitHub,欢迎各位能提出宝贵的意见噢 https://github.com...
- Grid:并行显示多张图表 注意: 第一个图需为 有 x/y 轴的图,即不能为 Pie,其他位置顺序任意 Over...
- echarts官方的api文档:Apache ECharts[https://echarts.apache.org...
- 在大屏的开发过程中,需要大量的使用echarts图表,我们可以腾出时间将echarts图表进行二次封装,以便后期循...