Browse Source

k线不出来修复

master
vee 3 years ago
parent
commit
d8e9ab3061
  1. BIN
      .DS_Store
  2. 173
      components/kline/kline.vue
  3. 58
      components/kline/tradingView/datafeed.js
  4. 130
      components/kline/tradingView/websocket.js
  5. 6
      manifest.json

BIN
.DS_Store

Binary file not shown.

173
components/kline/kline.vue

@ -1,4 +1,4 @@
<template> <template>
<view> <view>
<view class="tab"> <view class="tab">
<view class="item" :class="{ select: type === '1min' }" @click="onChangeType('1min')">1min <view class="item" :class="{ select: type === '1min' }" @click="onChangeType('1min')">1min
@ -17,26 +17,26 @@
</view> </view>
<view class="item" :class="{ select: type === '1mon' }" @click="onChangeType('1mon')">1mon <view class="item" :class="{ select: type === '1mon' }" @click="onChangeType('1mon')">1mon
</view> </view>
</view> </view>
<view id="kline" :windowWidth="width" :change:windowWidth="KlineJs.setWidth" :windowHeight="height" <view id="kline" :windowWidth="width" :change:windowWidth="KlineJs.setWidth" :windowHeight="height"
:change:windowHeight="KlineJs.setHeight" :symbol="symbol" :change:windowHeight="KlineJs.setHeight" :symbol="symbol"
:change:symbol="KlineJs.setSymbol" :language="lang" :change:language="KlineJs.changlanguage" :index_activeCycle="index_activeCycle" :change:index_activeCycle="KlineJs.changindex_activeCycle"></view> :change:symbol="KlineJs.setSymbol" :language="language" :change:language="KlineJs.changlanguage" :index_activeCycle="index_activeCycle" :change:index_activeCycle="KlineJs.changindex_activeCycle"></view>
</view> </view>
</template> </template>
<script> <script>
import props from './props.js' import props from './props.js'
export default { export default {
name: "kline", name: "kline",
mixins: [props], mixins: [props],
data() { data() {
return { return {
type:'1min', type:'1min',
index_activeCycle:1 index_activeCycle:1
}; };
}, },
created() { created() {
} }
,methods: { ,methods: {
onChangeType(type) { onChangeType(type) {
@ -84,81 +84,81 @@
break; break;
} }
}, },
} }
} }
</script> </script>
<script module="KlineJs" lang="renderjs"> <script module="KlineJs" lang="renderjs">
import { import {
widget widget
} from '@/static/charting_library/charting_library.js' } from '@/static/charting_library/charting_library.js'
import { import {
chartConfig chartConfig
} from './tradingView/chartConfig.js' } from './tradingView/chartConfig.js'
// //
var widgetObj = null var widgetObj = null
// //
var index_market = 'btcusdt' var index_market = 'btcusdt'
export default { export default {
data() { data() {
return { return {
chartHeight: 0, chartHeight: 0,
chartWidth: 0, chartWidth: 0,
chartSymbol:'btc', chartSymbol:'btc',
language:'en' language:'en'
} }
}, },
//renderjs //renderjs
mounted() { mounted() {
// //
this.initChart("1") this.initChart("1")
}, },
methods: { methods: {
setSymbol(symbol){ setSymbol(symbol){
//console.log(symbol) //console.log(symbol)
this.chartSymbol=symbol this.chartSymbol=symbol
}, },
setWidth(width) { setWidth(width) {
//console.log(":", width) //console.log(":", width)
this.chartWidth = width this.chartWidth = width
}, },
setHeight(height) { setHeight(height) {
//console.log(":", height) //console.log(":", height)
this.chartHeight = 300 this.chartHeight = 300
}, },
changindex_activeCycle(index_activeCycle){ changindex_activeCycle(index_activeCycle){
this.initChart(index_activeCycle) this.initChart(index_activeCycle)
}, },
changlanguage(language){ changlanguage(language){
chartConfig.locale=language this.language=language
} }
, ,
initChart(index_activeCycle) { initChart(index_activeCycle) {
// chartConfig chartConfig.js // chartConfig chartConfig.js
// chartConfig // chartConfig
chartConfig.interval = index_activeCycle chartConfig.interval = index_activeCycle
// chartConfig // chartConfig
chartConfig.symbol = this.symbol chartConfig.symbol = this.symbol
chartConfig.resolutions=[1]; chartConfig.resolutions=[1];
// //
chartConfig.width = this.chartWidth chartConfig.width = this.chartWidth
chartConfig.height = this.chartHeight chartConfig.height = this.chartHeight
chartConfig.time_frames=[] chartConfig.time_frames=[]
// TradingView // TradingView
//console.log(window.TradingView.version()) //console.log(window.TradingView.version())
widgetObj = new widget(chartConfig) widgetObj = new widget(chartConfig)
//console.log(11111,widgetObj) //console.log(11111,widgetObj)
widgetObj._options.interval=5 widgetObj._options.interval=5
widgetObj.onChartReady(() => { widgetObj.onChartReady(() => {
// k线 7线30线 // k线 7线30线
widgetObj.chart().createStudy('Moving Average', false, false, [5], null, { widgetObj.chart().createStudy('Moving Average', false, false, [5], null, {
'Plot.linewidth': 2, 'Plot.linewidth': 2,
'Plot.color': '#2ba7d6' 'Plot.color': '#2ba7d6'
}) })
widgetObj.chart().createStudy('Moving Average', false, false, [10], null, { widgetObj.chart().createStudy('Moving Average', false, false, [10], null, {
'Plot.linewidth': 2, 'Plot.linewidth': 2,
@ -172,21 +172,19 @@
'Plot.linewidth': 2, 'Plot.linewidth': 2,
'Plot.color': '#965fc4' 'Plot.color': '#965fc4'
}) })
this.$nextTick(() => { this.$nextTick(() => {
widgetObj.chart().resetData() widgetObj.chart().resetData()
}) })
}) })
}, },
} }
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.tab { .tab {
display: flex; display: flex;
background: #000000; background: #000000;
position: absolute;
width:100%;
.item { .item {
height: 64rpx; height: 64rpx;
line-height: 64rpx; line-height: 64rpx;
@ -204,5 +202,4 @@
} }
</style> </style>

58
components/kline/tradingView/datafeed.js

@ -15,7 +15,7 @@ import {
// 历史数据 第一条数据的 时间撮 因为k线图一次性历史数据只拿一部分,用户吧图往前滑动,就会用这个时间撮去请求更早的 历史数据 // 历史数据 第一条数据的 时间撮 因为k线图一次性历史数据只拿一部分,用户吧图往前滑动,就会用这个时间撮去请求更早的 历史数据
var detafeed_historyTime = 0 var detafeed_historyTime = null
// 上一次的 K线周期 切换产品的时候 需要从websock 取消订阅这个 // 上一次的 K线周期 切换产品的时候 需要从websock 取消订阅这个
var detafeed_lastResolution = null var detafeed_lastResolution = null
// 上一次的产品 切换产品的时候 需要从websock 取消订阅这个 // 上一次的产品 切换产品的时候 需要从websock 取消订阅这个
@ -32,7 +32,7 @@ FeedBase.prototype.getSendSymbolName = function(symbolName) {
var name = symbolName.split('/') var name = symbolName.split('/')
return (name[0] + name[1]).toLocaleLowerCase() return (name[0] + name[1]).toLocaleLowerCase()
} }
FeedBase.prototype.resolveSymbol = function(symbolName, onResolve, onError) { FeedBase.prototype.resolveSymbol = function(symbolName, onResolve, onError) {
onResolve({ onResolve({
"name": symbolName, "name": symbolName,
@ -45,10 +45,15 @@ FeedBase.prototype.resolveSymbol = function(symbolName, onResolve, onError) {
"session": "24x7", "session": "24x7",
"type": "bitcoin", "type": "bitcoin",
"volume_precision": 10, "volume_precision": 10,
"has_intraday": true, "has_intraday": true,
"intraday_multipliers": ['1', '5', '15', '30', '60', '240', '1440'], // 时间 "seconds_multipliers":['1', '5', '15', '30', '60', '1D', '1W','1M'],
"has_weekly_and_monthly": false, "intraday_multipliers": ['1', '5', '15', '30', '60', '1D', '1W','1M'],
"has_no_volume": false, "has_seconds":true,
"supports_marks": true,
"supports_timescale_marks": true,
"supported_time": true,
"has_weekly_and_monthly": true,
"has_no_volume": true,
"regular_session": "24x7", "regular_session": "24x7",
}) })
@ -65,7 +70,7 @@ FeedBase.prototype.resolveSymbol = function(symbolName, onResolve, onError) {
const resolutionFormat = (resolution, name, to) => { const resolutionFormat = (resolution, name, to) => {
let req = `market.${name}.kline.${resolution}min`; let req = `market.${name}.kline.${resolution}min`;
let minutes = resolution; let minutes = resolution;
console.log(resolution)
if (resolution.includes('D')) { if (resolution.includes('D')) {
if (resolution.length < 2) resolution = '1' + resolution; if (resolution.length < 2) resolution = '1' + resolution;
req = `market.${name}.kline.${parseInt(resolution)}day`; req = `market.${name}.kline.${parseInt(resolution)}day`;
@ -86,11 +91,12 @@ const resolutionFormat = (resolution, name, to) => {
let from = null; let from = null;
if (to) { if (to) {
from = to - 50 * minutes * 60; from = to - 50 * minutes * 500;
if (resolution.includes('M') || resolution.includes('W')) { // 周线月线控制条数,时间超出火币规定范围, ws报错 if (resolution.includes('M') || resolution.includes('W')) { // 周线月线控制条数,时间超出火币规定范围, ws报错
from = to - 50 * minutes * 60; from = to - 50 * minutes * 500;
} }
} }
return { return {
minutes, minutes,
req, req,
@ -100,11 +106,13 @@ const resolutionFormat = (resolution, name, to) => {
}; };
FeedBase.prototype.getBars = function(symbolInfo, resolution, periodParams, onHistoryCallback, onErrorCallback) { FeedBase.prototype.getBars = function(symbolInfo, resolution, periodParams, onHistoryCallback, onErrorCallback) {
console.log("获取历史数据") console.log("获取历史数据",periodParams)
// 切换产品周期 或者 切换产品 会执行这个函数 // 切换产品周期 或者 切换产品 会执行这个函数
let reso = resolutionFormat(resolution, symbolInfo.name, periodParams.to > detafeed_historyTime ? periodParams let reso = resolutionFormat(resolution, symbolInfo.name, periodParams.to)
.to : // if (resolution.includes('M') || resolution.includes('W')|| resolution.includes('D')) { // 周线月线控制条数,时间超出火币规定范围, ws报错
detafeed_historyTime) // reso = resolutionFormat(resolution, symbolInfo.name, periodParams.to)
// }
// 是历史数据 // 是历史数据
var history = true var history = true
/* /*
@ -127,16 +135,19 @@ FeedBase.prototype.getBars = function(symbolInfo, resolution, periodParams, onHi
第二个参数订阅实时数据 第二个参数订阅实时数据
第三个参数 是否是历史数据 第三个参数 是否是历史数据
*/ */
socket.sendData({ socket.sendData({
req: reso.req, event: "req",
id: "id10", type: "kline",
from: reso.from, channel: [reso.req],
to: reso.to, fromDate:reso.from,
toDate:reso.to
}, reso.req, history) }, reso.req, history)
Event.off('data') Event.off('data')
Event.on('data', data => { Event.on('data', data => {
if (data && Array.isArray(data)) { if (data && Array.isArray(data)) {
// 记录这次请求的时间周期 // 记录这次请求的时间周期
detafeed_lastResolution = resolution detafeed_lastResolution = resolution
@ -151,13 +162,14 @@ FeedBase.prototype.getBars = function(symbolInfo, resolution, periodParams, onHi
i.volume = i.vol i.volume = i.vol
datas.push(i) datas.push(i)
} }
} else { } else {
console.log('进来')
meta = { meta = {
noData: true, noData: 'no_data',
nextTime: detafeed_historyTime nextTime: detafeed_historyTime
} }
} }
onHistoryCallback(datas, meta) onHistoryCallback(datas, {noData:data.length==0})
} }
}) })
} }

130
components/kline/tradingView/websocket.js

@ -1,45 +1,47 @@
import
constant
from '@/utils/constant.js'
import { import {
Event Event
} from './event.js' } from './event.js'
import pakoJs from './pako.js' import pakoJs from './pako.js'
var pako = pakoJs var pako = pakoJs
var socket = { var socket = {
socket: null, // socket name socket: null, // socket name
id:null,
realTimeData: null, // 请求实时数据的参数 realTimeData: null, // 请求实时数据的参数
intervalObj: null, // 定时器的名字 intervalObj: null, // 定时器的名字
lastRealTimeData: null, // 上一次请求的产品 lastRealTimeData: null, // 上一次请求的产品
sendData(historyData, realTimeDatas, history) { sendData(historyData, realTimeDatas, history) {
// 储存历史数据 // 储存历史数据
this.historyData = historyData this.historyData = historyData
this.realTimeData = realTimeDatas this.realTimeData = realTimeDatas
// 如果上一次订阅过产品 // 如果上一次订阅过产品
if (this.lastRealTimeData) { if (this.lastRealTimeData) {
// 如果不是订阅历史产品 那么肯定就是切换周期咯 或者 切换产品
// 那么就取消订阅上一次的产品实时数据
if (!history) {
console.log('取消订阅' + this.lastRealTimeData)
this.sendWsRequest({
"unsub": this.lastRealTimeData,
"id": "id1"
})
}
// 请求这一次的历史 // 请求这一次的历史
this.historyData.id=this.id
this.sendWsRequest(this.historyData) this.sendWsRequest(this.historyData)
console.log(111111,realTimeDatas)
// 如果不是订阅历史产品 那么肯定就是切换周期咯 或者切换产品咯 // 如果不是订阅历史产品 那么肯定就是切换周期咯 或者切换产品咯
// 那么就订阅一下 这次产品的或者周期的 实时数据 // 那么就订阅一下 这次产品的或者周期的 实时数据
if (!history) { if (!history) {
console.log('订阅新的' + realTimeDatas) //console.log('订阅新的' + realTimeDatas)
this.sendWsRequest({ //console.log(111111,realTimeDatas)
"sub": realTimeDatas, this.sendWsRequest({
"id": "id1" event: 'un_sub',
}) type: 'kline',
id: this.id,
channel:[this.lastRealTimeData],
})
this.lastRealTimeData = this.realTimeData
} }
} else { } else {
// 如果是第一次订阅,就是说刚进入交易所, // 如果是第一次订阅,就是说刚进入交易所,
// 先存起来这一次请求的产品 作为历史产品 // 先存起来这一次请求的产品 作为历史产品
this.lastRealTimeData = this.realTimeData this.lastRealTimeData = this.realTimeData
@ -48,13 +50,9 @@ var socket = {
} }
}, },
initWs() { initWs() {
this.socket = new WebSocket('wss://api.huobi.pro/ws') this.socket = new WebSocket(constant.WSSURL)
this.socket.onopen = () => { this.socket.onopen = () => {
this.sendWsRequest(this.historyData)
this.sendWsRequest({
"sub": this.historyData.req,
"id": "id1"
})
} }
this.socket.onmessage = resp => { this.socket.onmessage = resp => {
this.message(resp) this.message(resp)
@ -67,46 +65,52 @@ var socket = {
} }
}, },
error(err) { error(err) {
console.log(err, 'depth-socket::error') //console.log(err, 'depth-socket::error')
}, },
close() { close() {
// 如果websocket关闭的话,就从新打开一下。 // 如果websocket关闭的话,就从新打开一下。
this.initWs() this.initWs()
console.log('depth-socket::close') //console.log('depth-socket::close')
}, },
message(resp) { message(resp) {
//console.log(resp) resp=JSON.parse(resp.data)
let this_ = this if (resp.channel === 'conn') {
let reader = new FileReader() this.id = resp.data
reader.onload = function(e) {
// 对数据进行解压 this.historyData.id=this.id
let msg = JSON.parse(pako.ungzip(reader.result, { this.sendWsRequest(this.historyData)
to: 'string'
}))
// console.log(msg) }else {
// 如果是实时数据触发Event('realTime') 喂数据 if(resp.event === 'req'){
if (msg.tick) {
Event.emit('realTime', msg.tick) //Event.emit('data', resp.data)
} if (resp.data && Array.isArray(resp.data)) {
Event.emit('data', resp.data)
//响应服务器,避免断开连接 }
if (msg.ping) { this.sendWsRequest({
this_.socket.send(JSON.stringify({ event: 'un_sub',
pong: msg.ping type: 'kline',
})); id: this.id,
this_.hasCheck = true channel:[this.lastRealTimeData],
} })
this.sendWsRequest({
this_.lastRealTimeData = this_.realTimeData event: 'sub',
// 如果是历史数据触发Event('data') 绘制数据 type: 'kline',
if (msg.data && Array.isArray(msg.data)) { id: this.id,
console.log(msg.data) channel:[this.lastRealTimeData],
Event.emit('data', msg.data) })
} }else{
}
// //将返回的数据解析为字符串格式 Event.emit('realTime', resp.data)
reader.readAsArrayBuffer(resp.data);
}
}
}, },
checkSendMessage(options) { checkSendMessage(options) {
// 这里处理websocket 连接不上的问题 // 这里处理websocket 连接不上的问题
@ -122,7 +126,7 @@ var socket = {
} }
if (i >= checkTimes) { if (i >= checkTimes) {
clearInterval(this.intervalObj) clearInterval(this.intervalObj)
console.log('send post_data_str timeout.') //console.log('send post_data_str timeout.')
} }
}, 500) }, 500)
}, },
@ -135,13 +139,13 @@ var socket = {
this.socket.send(JSON.stringify(options)) this.socket.send(JSON.stringify(options))
break break
case 2: case 2:
console.log('ws关闭状态') //console.log('ws关闭状态')
break break
case 3: case 3:
this.initWs() this.initWs()
break break
default: default:
console.log('ws未知错误') //console.log('ws未知错误')
} }
} }
} }

6
manifest.json

@ -2,8 +2,8 @@
"name" : "Same home", "name" : "Same home",
"appid" : "__UNI__C4028F6", "appid" : "__UNI__C4028F6",
"description" : "", "description" : "",
"versionName" : "1.0.1", "versionName" : "1.0.3",
"versionCode" : 101, "versionCode" : 103,
"transformPx" : false, "transformPx" : false,
/* 5+App */ /* 5+App */
"app-plus" : { "app-plus" : {
@ -119,7 +119,7 @@
}, },
"/market" : { "/market" : {
"ws" : false, "ws" : false,
"target" : "https://market.acefinex.com", "target" : "https://market.gream.ltd",
"changeOrigin" : true, "changeOrigin" : true,
"secure" : false, "secure" : false,
"pathRewrite" : { "pathRewrite" : {

Loading…
Cancel
Save