这里是前端绘图的代码,是这里解压出来的文件夹的根目录中main.html的代码
<!DOCTYPE HTML>
<html>
<head>
<title>TradingView</title>
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<script type="text/javascript" src="./charting_library/charting_library.min.js"></script>
<script type="text/javascript" src="./datafeeds/udf/dist/polyfills.js"></script>
<script type="text/javascript" src="./datafeeds/udf/dist/bundle.js"></script>
</head>
<body style="margin:0px;">
<div id='sss'>
<div id="tv_chart_container"></div>
<script>
getWs();
//建立长连接,长连接服务的代码在下一篇讲
function getWs(){
var url = 'ws://127.0.0.1:9502/basis_mode_test';
socket = new WebSocket(url);
socket.onopen = () => {
console.log('建立长连接')
}
socket.onclose = () => {
console.log("断开链接");
}
socket.onerror = () => {
console.log("出错了");
};
}
function getParameterByName(name) {
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
//支持的时间间隔,5分钟,1小时,1天
var config = {
supported_resolutions: ["5", "60", "1D"],
};
var datafeed = {
onReady: cb => {
console.log("=====onReady running");
cb(config);
},
//搜索,在左上角搜索的时候,这里的列表会生成一个下拉选择框
searchSymbols: (userInput, exchange, symbolType, onResultReadyCallback) => {
var pathList = [
"btc",
"ltc",
"etc"
];
var list = [];
for (var path of pathList) {
var pathUp = path.toUpperCase();
for(var mode of ['_AB','_BA']){
var str = pathUp+mode;
if(str.indexOf(userInput) != -1){
list.push(
{
"symbol": pathUp,
"full_name": str,
"description": mode,
"exchange": str,
"type":'bitcoin'
}
);
}
}
}
onResultReadyCallback(list);
},
//商品配置
resolveSymbol: (symbolName, onSymbolResolvedCallback, onResolveErrorCallback) => {
console.log(symbolName)
var symbol_stub = {
name: symbolName,
description: "",
has_intraday: true,
has_no_volume: false,
minmov: 1,
minmov2: 0,
pricescale: 10000,
session: "24x7",
supported_resolutions: ["5", "60", "1D"],
ticker: symbolName,
timezone: "Asia/Shanghai",
type: "bitcoin"
}
onSymbolResolvedCallback(symbol_stub);
},
//这里做的事,更新历史数据,注册onMessage回调,触发实时更新的回调方法
getBars: (symbolInfo, resolution, from, to, onHistoryCallback, onErrorCallback, firstDataRequest) => {
//渲染历史数据
function _send (data) {
let bars = [];
if (data.data.length != 0) {
data.data.forEach(e => {
var _bar = {
time:parseInt(e.create_time),
close:parseFloat(e.close),
open:parseFloat(e.open),
high:parseFloat(e.tallest),
low:parseFloat(e.lowest),
}
bars.push(_bar);
});
meta = {
noData: false,
};
} else {
meta = {
noData: true,
}
}
console.log(meta);
for (const his of window.historyList) {
if(his.sym.name == data.name && his.from == data.from && his.to == data.to && his.resolution == data.resolution){
his.callback(bars,meta)
}
}
// 触发回调
// onHistoryCallback(bars, meta)
}
if(!window.parent.socket) return;
//当长连接返回数据时,触发这里的代码
window.parent.socket.onmessage = e =>{
if(e.data == ''){
return ;
}
let data = JSON.parse(e.data);
// console.log(data);
//如果长连接返回的方法名是KlineHistory,则渲染历史数据
if(data.method == "KlineHistory"){
_send(data);
}
//如果长连接返回的方法名是KlineUpdata,则更新最后一条K线,或新增一条K线
if(data.method == 'KlineUpdata'){
for (const sub of window.SubscriberList) {
if(sub.id == data.id){
var bar = {
time:parseInt(data.data.time),
close:parseFloat(data.data.close),
open:parseFloat(data.data.open),
high:parseFloat(data.data.tallest),
low:parseFloat(data.data.lowest),
};
sub.callback(bar);
}
}
}
}
console.log('获取历史数据'+symbolInfo.name+'--'+resolution);
console.log(symbolInfo == symbolInfo);
//注册多个历史数据的回调,多条线展示的时候,能分得清哪个回调用哪个数据
if(!window.historyList){
window.historyList = [];
}
window.historyList.push({
sym:symbolInfo,
from:from,
to:to,
resolution:resolution,
callback:onHistoryCallback
});
//向长连接发消息,触发ws服务的KlineHistory方法
window.parent.socket.send(JSON.stringify({
method: 'KlineHistory',
data: {
//path
market: symbolInfo.name,
//起始时间
from: from,
//结束时间
to: to,
//间隔 5m
resolution: resolution,
}
}));
},
//实时更新
subscribeBars: (symbolInfo, resolution, onRealtimeCallback, subscriberUID,onResetCacheNeededCallback) => {
//注册多个更新实时数据的回调,多条线展示的时候,能分得清哪个回调用哪个数据
if(!window.SubscriberList){
window.SubscriberList = [];
}
window.SubscriberList.push(
{
symbol: symbolInfo,
resolution: resolution,
id: subscriberUID.toLowerCase(),
callback: onRealtimeCallback
}
);
console.log('发送subscribeBars')
//向长连接发消息,触发ws服务的KlineUpdata方法
window.parent.socket.send(JSON.stringify({
method: 'KlineUpdata',
data: {
//path
market: symbolInfo.name,
//间隔
resolution: resolution,
id:subscriberUID
}
}));
},
//取消订阅,撤销掉某条线的实时更新
unsubscribeBars:(subscriberUID)=>{
console.log('取消订阅'+subscriberUID);
window.parent.socket.send(JSON.stringify({
method:'removeSubscriber',
id:subscriberUID,
}));
const idx = window.SubscriberList.findIndex(n => n.id === subscriberUID)
if (idx < 0) return
window.SubscriberList.splice(idx, 1)
}
}
//基本配置
const widgetOptions = {
// debug: true, // uncomment this line to see Library errors and warnings in the console
fullscreen: true, // 是否全屏
symbol: "btc", // 默认商品标识
interval: '5', // 初始化显示时间范围
container_id: "tv_chart_container", // 容器的id名
// 调用接口API hrc_usdt
datafeed: datafeed,
library_path: "./charting_library/", //调用本js图表地库和样式
// 语言 en英文 zh 中文
locale: getParameterByName('lang') || "zh",
// disabled_features: [],// 禁用功能
enabled_features: ["study_templates"],
disabled_features: ["use_localstorage_for_settings"],
charts_storage_url: 'http://saveload.tradingview.com',
charts_storage_api_version: "1.1",
client_id: 'tradingview.com',
user_id: 'public_user_id',
theme: getParameterByName('theme'),
timeframe:'1D',
timezone:'Asia/Shanghai',
autosize:true
}
var widget = window.tvWidget = new TradingView.widget(widgetOptions);
</script>
</div>
</body>
</html>