vue2 k线组件
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

327 lines
12 KiB

var tvBlackBgColor = '#f5f5f5' // 黑色背景色
var tvIntervalList = ['1', '5', '15', '30', '60', '240', 'D', 'W'] // 所有周期
var tvIntradayMultipliers = ['1', '5', '15', '30', '60', '240'] // 日内周期
var realtimeFlag = false;
var kcCurrentData = {};
var lastBarTime = parseInt(Date.now() / 1000);
var loadMoreFlag = false;
/**
* 一个对象,往上面挂[id]: callback;
* id为键,对应一个请求历史数据的请求,
* callback是该请求历史数据返回的回调函数,
* 且回调函数会延时清理自身过期id callback
* {
* 1: function(){}
* 2: function(){}
* }
*/
var kcHistoryKeyId = 1 // 自增id,本地维护
var kcHistoryCallbackMap = {}
var kcSocket = null // websocket 实例
var kcSubscribeId = 3601 // 自增id, 本地维护
var kcChart = null;
// 获取当前交易对 如BTC/USDT
function getSymbol() {
return kcCurrentData.symbol || (kcCurrentData.coinSymbol + '/' + kcCurrentData.baseSymbol)
}
// 设置可见K线范围
function setKLineVisibleRange(lastBarTime_t, barsCount) {
var count = barsCount || 300 // 显示几条k线
var interval = kcCurrentData.interval
var to = parseInt(lastBarTime_t) // 历史数据的最后一条柱子的时间
var toNum = 20 // 多显示几条k线距离
var seconds = getSecondsByInterval(interval); // 秒数
var options = {
from: to - (seconds * count),
to: to, // 可见的结束时间,因为结束时间可能不是当前时间,为了与右边价格刻度有一点距离所以加toNum条柱子的时间
interval: seconds
}
return options;
}
// 周期转换为秒
function getSecondsByInterval(interval) {
// 周期 ['1', '5', '15', '30', '60', '240', 'D', 'W']
interval = interval || kcCurrentData.interval;
var map = {
'1': 60,
'5': 60 * 5,
'15': 60 * 15,
'30': 60 * 30,
'60': 60 * 60,
'240': 60 * 240,
'D': 60 * 60 * 24,
'W': 60 * 60 * 24 * 7
}
return map[interval + '']
}
function loadMoreKline(data, is_first, key){
if(key == kcHistoryKeyId) {
is_first = is_first || false;
if (is_first) {
kcChart.clearData();
}
if (data != null || data != '' || data != undefined) {
var dataArr = [];
var dataArr_index = 0;
$.each(data, function (index, item) {
try {
if (typeof item == 'string') {
item = JSON.parse(item);
}
dataArr[dataArr_index] = {
timestamp: Number(item[0] * 1000),
open: Number(item[1]),
high: Number(item[3]),
low: Number(item[4]),
close: Number(item[2]),
volume: Number(item[5])
};
// if(kcCurrentData.interval == 'D' || kcCurrentData.interval == 'W') dataArr[dataArr_index].timestamp += 57600000;
dataArr_index++;
} catch (e) {
}
})
console.log(dataArr);
// kcHistoryKeyId++;
if (dataArr.length <= 0) {
kcChart.applyMoreData(dataArr, false);
} else {
lastBarTime = (dataArr[0].timestamp / 1000) - getSecondsByInterval();
console.log(lastBarTime);
kcChart.applyMoreData(dataArr, true);
}
}
}
}
// $('.interval_btn').on('click', function(){
// console.log('11111');
// if(kcChart != null || kcChart != undefined){
// var _this = $(this);
// kcCurrentData.interval = _this.attr('data-interval');
// // 请求历史数据
// kcHistoryKeyId = 1;
// var rang = setKLineVisibleRange(parseInt(Date.now() / 1000));
// $.ajax({
// url: "https://dfmg.dficoins.com/api/getkkline",
// type: 'get',
// async: false,
// data: {
// symbol: getSymbol(),
// interval: getSecondsByInterval(kcCurrentData.interval),
// times: kcHistoryKeyId,
// from: rang.from,
// to: rang.to + (365 * 86400)
// },
// beforeSend: function(){
// loading_index = layer.load(1, {
// shade: [0.1, '#fff'] //0.1透明度的白色背景
// });
// },
// success:function (result) { //成功回调
// console.log(result);
// if(result.status){
// loadMoreKline(result.data, true, result.code);
// $('.interval_btn').removeClass('active');
// _this.addClass('active');
// }else{
// }
// layer.close(loading_index);
// },
// error: function(xhr){
// layer.close(loading_index);
// }
// });
// }
// })
// 初始化tv
function initKlineChart() {
kcChart = klinecharts.init(kcCurrentData.containerId);
kcChart.setTimezone(kcCurrentData.timezone);
kcChart.setOffsetRightSpace(20);
// 创建一个主图指标
kcChart.createTechnicalIndicator({ name: 'VOL', calcParams: [10], styles: { margin: { top: 0.2, bottom: 2 } } })
kcChart.createTechnicalIndicator({
name: 'MA',
shortName: 'MA',
calcParams: [10, 20, 30],
dragEnabled: true,
plots: [
{ key: 'ma1', title: 'MA10: ', type: 'line' },
{ key: 'ma2', title: 'MA20: ', type: 'line' },
{ key: 'ma3', title: 'MA30: ', type: 'line' }
],
// 当计算参数改变时,希望提示的和参数一样,即title的值需要改变
regeneratePlots: (params) => {
return params.map((p, i) => {
return { key: `ma${i + 1}`, title: `MA${p}: `, type: 'line' }
})
},
// 计算结果
calcTechnicalIndicator: (kLineDataList, { params, plots }) => {
// 注意:返回数据个数需要和kLineDataList的数据个数一致,如果无值,用{}代替即可。
// 计算参数最好取回调参数params,如果不是,后续计算参数发生变化的时候,这里计算不能及时响应
const closeSums = []
return kLineDataList.map((kLineData, i) => {
const ma = {}
const close = kLineData.close
params.forEach((param, j) => {
closeSums[j] = (closeSums[j] || 0) + close
if (i >= param - 1) {
ma[plots[j].key] = closeSums[j] / param
closeSums[j] -= dataList[i - (param - 1)].close
}
})
// 如果有值的情况下,这里每一项的数据格式应该是 { ma1: xxx, ma2: xxx }
// 每个key需要和plots中的子项key对应的值一致
return ma
})
}
}, true, {
id: 'candle_pane',
dragEnabled: true
});
kcChart.setPriceVolumePrecision(kcCurrentData.coinScale, kcCurrentData.volumeScale);
kcChart.loadMore(function () {
setTimeout(function(){
if(loadMoreFlag) {
loadMoreFlag = false;
var rang = setKLineVisibleRange(lastBarTime);
$.ajax({
url: "https://dfmg.dficoins.com/api/getkkline",
type: 'get',
async: false,
data: {
symbol: getSymbol(),
interval: getSecondsByInterval(kcCurrentData.interval),
times: kcHistoryKeyId,
from: rang.from,
to: rang.to
},
success: function (result) { //成功回调
console.log(result);
if (result.status) {
loadMoreKline(result.data, false, result.code);
loadMoreFlag = true;
} else {
}
}
});
}
}, kcHistoryKeyId == 1 ? 500 : 10);
})
kcChart.setStyleOptions({
// 蜡烛图
candle: {
// 提示
tooltip: {
// 'always' | 'follow_cross' | 'none'
showRule: 'always',
// 'standard' | 'rect'
showType: 'rect',
labels: [
langData[kcCurrentData.language].time,
langData[kcCurrentData.language].open,
langData[kcCurrentData.language].close,
langData[kcCurrentData.language].high,
langData[kcCurrentData.language].low,
langData[kcCurrentData.language].volume
],
values: null,
defaultValue: '--',
rect: {
paddingLeft: 0,
paddingRight: 0,
paddingTop: 0,
paddingBottom: 6,
offsetLeft: 8,
offsetTop: 20,
offsetRight: 8,
borderRadius: 4,
borderSize: 1,
borderColor: '#3f4254',
backgroundColor: 'rgba(17, 17, 17, .3)'
},
text: {
size: 12,
family: 'Helvetica Neue',
weight: 'normal',
color: '#fff',
marginLeft: 8,
marginTop: 6,
marginRight: 8,
marginBottom: 0
}
}
}
});
var rang = setKLineVisibleRange(lastBarTime);
$.ajax({
url: "https://dfmg.dficoins.com/api/getkkline",
type: 'get',
async: false,
data: {
symbol: getSymbol(),
interval: getSecondsByInterval(kcCurrentData.interval),
times: kcHistoryKeyId,
from: rang.from,
to: rang.to + (365 * 86400)
},
beforeSend: function(){
loading_index = layer.load(1, {
shade: [0.1, '#fff'] //0.1透明度的白色背景
});
},
success:function (result) { //成功回调
console.log(result);
if(result.status){
loadMoreKline(result.data, true, result.code);
loadMoreFlag = true;
$('.interval_btn').removeClass('active');
$('.interval_btn[data-interval="' + result.msg + '"]').addClass('active');
}else{
layer.msg(result.msg, {icon: 2});
}
layer.close(loading_index);
},
error: function(xhr){
layer.close(loading_index);
}
});
}
// 先引入这个JS文件,然后在websocket连接成功后,调用这个方法,启动TradingView
/**
* 启动
* @param {Object} _ws 已经连接成功的Websocket对象
* @param {Object} _config Tv配置项,计价币种和交易币种必须要传入
*/
function kcStart(_config){
// 重要:k线图配置的重要数据,当前k线维护的一份数据,k线切换时,改变周期时都要变对应的值
kcCurrentData = {
containerId: _config.containerId,
baseSymbol: _config.baseSymbol, // 计价币种
coinSymbol: _config.coinSymbol, // 交易币种
symbol: _config.symbol || '--',
coinScale: _config.coinScale || 2, // 计价币种精度
volumeScale: _config.volumeScale || 2, // 成交量精度保留
interval: _config.interval || '15', // 15分钟
bgColor: _config.bgColor || tvBlackBgColor, // 当前选择背景色
language: _config.language || 'en',
timezone: _config.timezone || 'Asia/Shanghai'
}
initKlineChart()
}