|
@@ -4,19 +4,34 @@
|
|
<div class="page_wp">
|
|
<div class="page_wp">
|
|
<div class="content_wp">
|
|
<div class="content_wp">
|
|
<div class="content_top_wp">
|
|
<div class="content_top_wp">
|
|
- <div class="exchange_wp">
|
|
|
|
- <div :class="{ exchange_item: true, selected: selectedExchangeList.includes(item) }" v-for="item in exchangeList" @click="handleExchange(item)">
|
|
|
|
- {{ item }}
|
|
|
|
|
|
+ <div class="custom-form-layout">
|
|
|
|
+ <div class="custom-checkbox">
|
|
|
|
+ <div class="label">交易所</div>
|
|
|
|
+ <div class="checkbox-group">
|
|
|
|
+ <div class="checkbox-wp">
|
|
|
|
+ <lay-checkcard-group v-model="selectedExchangeList">
|
|
|
|
+ <lay-checkcard v-for="item of exchangeList" :value="item" :title="item" @click="handleExchange(item)" />
|
|
|
|
+ </lay-checkcard-group>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
- <div class="symbol_wp">
|
|
|
|
- <div class="symbol_label">币对:</div>
|
|
|
|
- <lay-select v-model="selectedSymbol" :show-search="true" @change="handleSelectedSymbol">
|
|
|
|
- <lay-select-option v-for="item in symbolList" :keyword="item.toLocaleLowerCase()" :value="item" :label="item" />
|
|
|
|
- </lay-select>
|
|
|
|
|
|
+ <div class="custom-form-layout">
|
|
|
|
+ <div class="custom-checkbox">
|
|
|
|
+ <div class="label">时间(小时):</div>
|
|
|
|
+ <lay-input-number :step-strictly="true" v-model="dayNum" placeholder="单位(小时)" />
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="custom-form-layout">
|
|
|
|
+ <div class="custom-checkbox">
|
|
|
|
+ <div class="label">币对:</div>
|
|
|
|
+ <lay-select v-model="selectedSymbol" :show-search="true" @change="handleSelectedSymbol">
|
|
|
|
+ <lay-select-option v-for="item in symbolList" :keyword="item.toLocaleLowerCase()" :value="item" :label="item" />
|
|
|
|
+ </lay-select>
|
|
|
|
+ </div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
- <div class="operator_wp" v-show="false">
|
|
|
|
|
|
+ <div class="operator_wp" v-show="true">
|
|
<lay-space>
|
|
<lay-space>
|
|
<div class="item_wp">
|
|
<div class="item_wp">
|
|
<div class="label">自动刷新</div>
|
|
<div class="label">自动刷新</div>
|
|
@@ -27,7 +42,7 @@
|
|
<div class="content_bottom_wp">
|
|
<div class="content_bottom_wp">
|
|
<lay-loading :loading="chartLoading">
|
|
<lay-loading :loading="chartLoading">
|
|
<div class="chart_wp">
|
|
<div class="chart_wp">
|
|
- <div id="chart"></div>
|
|
|
|
|
|
+ <div id="chart" ref="chartRef"></div>
|
|
</div>
|
|
</div>
|
|
</lay-loading>
|
|
</lay-loading>
|
|
</div>
|
|
</div>
|
|
@@ -38,10 +53,12 @@
|
|
</template>
|
|
</template>
|
|
<script lang="ts" setup name="Depth">
|
|
<script lang="ts" setup name="Depth">
|
|
import { ref, shallowRef, reactive, watch, onUnmounted } from "vue";
|
|
import { ref, shallowRef, reactive, watch, onUnmounted } from "vue";
|
|
-import { init, getInstanceByDom } from "echarts";
|
|
|
|
|
|
+import * as echarts from "echarts";
|
|
import dayjs from "dayjs";
|
|
import dayjs from "dayjs";
|
|
import { get_exchange, get_coin, get_depth, get_incremental_depth } from "@/api";
|
|
import { get_exchange, get_coin, get_depth, get_incremental_depth } from "@/api";
|
|
|
|
|
|
|
|
+let chartRef = ref();
|
|
|
|
+
|
|
let pageLoading = ref(true);
|
|
let pageLoading = ref(true);
|
|
let chartLoading = ref(true);
|
|
let chartLoading = ref(true);
|
|
|
|
|
|
@@ -50,6 +67,7 @@ let selectedExchangeList = ref<Array<string>>([]);
|
|
|
|
|
|
let symbolList = ref<Array<string>>([]);
|
|
let symbolList = ref<Array<string>>([]);
|
|
let selectedSymbol = ref();
|
|
let selectedSymbol = ref();
|
|
|
|
+let dayNum = ref(2);
|
|
let isUpdate = ref(false);
|
|
let isUpdate = ref(false);
|
|
|
|
|
|
interface SymbolInfo {
|
|
interface SymbolInfo {
|
|
@@ -70,7 +88,7 @@ watch(isUpdate, (value) => {
|
|
clearInterval(timer.value);
|
|
clearInterval(timer.value);
|
|
timer.value = setInterval(() => {
|
|
timer.value = setInterval(() => {
|
|
getIncrementalDepth();
|
|
getIncrementalDepth();
|
|
- }, 1000);
|
|
|
|
|
|
+ }, 5000);
|
|
} else {
|
|
} else {
|
|
clearInterval(timer.value);
|
|
clearInterval(timer.value);
|
|
}
|
|
}
|
|
@@ -138,7 +156,7 @@ const handleSelectedSymbol = (value: any) => {
|
|
|
|
|
|
// 获取深度信息
|
|
// 获取深度信息
|
|
const getDepthInfo = (symbol: string) => {
|
|
const getDepthInfo = (symbol: string) => {
|
|
- const params = { exchange: selectedExchangeList.value.join(","), coin: symbol };
|
|
|
|
|
|
+ const params = { exchange: selectedExchangeList.value.join(","), coin: symbol, dayNum: dayNum.value };
|
|
chartLoading.value = true;
|
|
chartLoading.value = true;
|
|
get_depth(params, (data: any) => {
|
|
get_depth(params, (data: any) => {
|
|
chartLoading.value = false;
|
|
chartLoading.value = false;
|
|
@@ -158,7 +176,7 @@ const getIncrementalDepth = () => {
|
|
get_incremental_depth(params, (data: any) => {
|
|
get_incremental_depth(params, (data: any) => {
|
|
if (data.code == 200) {
|
|
if (data.code == 200) {
|
|
if (data.data.values.length > 0) {
|
|
if (data.data.values.length > 0) {
|
|
- let newSeries = handleSeries(data.data.values);
|
|
|
|
|
|
+ let newSeries = handleSeries(data.data.values, data.data.time.length);
|
|
let isUpdate = false;
|
|
let isUpdate = false;
|
|
series.value = newSeries.map((item: any) => {
|
|
series.value = newSeries.map((item: any) => {
|
|
let oldData = series.value.find((items: any) => {
|
|
let oldData = series.value.find((items: any) => {
|
|
@@ -167,7 +185,6 @@ const getIncrementalDepth = () => {
|
|
});
|
|
});
|
|
if (oldData) {
|
|
if (oldData) {
|
|
oldData.data = oldData.data.slice(item.data.length);
|
|
oldData.data = oldData.data.slice(item.data.length);
|
|
- // oldData.data = oldData.data.slice(0, oldData.data.length - 5);
|
|
|
|
oldData.data.push(...item.data);
|
|
oldData.data.push(...item.data);
|
|
isUpdate = true;
|
|
isUpdate = true;
|
|
}
|
|
}
|
|
@@ -175,7 +192,6 @@ const getIncrementalDepth = () => {
|
|
});
|
|
});
|
|
if (isUpdate) {
|
|
if (isUpdate) {
|
|
times.value = times.value.slice(data.data.time.length);
|
|
times.value = times.value.slice(data.data.time.length);
|
|
- // times.value = times.value.slice(0, times.value.length - 5);
|
|
|
|
times.value.push(...data.data.time);
|
|
times.value.push(...data.data.time);
|
|
isUpdate = false;
|
|
isUpdate = false;
|
|
}
|
|
}
|
|
@@ -195,49 +211,58 @@ const getIncrementalDepth = () => {
|
|
});
|
|
});
|
|
};
|
|
};
|
|
|
|
|
|
-const handleSeries = (data: any) => {
|
|
|
|
- let series: Array<any> = [];
|
|
|
|
|
|
+const handleSeries = (data: any, length: any = -1) => {
|
|
|
|
+ let newSeries: Array<any> = [];
|
|
|
|
+ let lastSeries = (series.value || [])
|
|
|
|
+ .map((item: any) => ({ [item.remark]: item.data[item.data.length - 1].value }))
|
|
|
|
+ .reduce((acc: any, current: any) => {
|
|
|
|
+ return { ...acc, ...current };
|
|
|
|
+ }, {});
|
|
|
|
+
|
|
for (let item of data) {
|
|
for (let item of data) {
|
|
let ask = item.ask.map((price: any) => ({ value: price, name: `${item.exchange}_ASK` }));
|
|
let ask = item.ask.map((price: any) => ({ value: price, name: `${item.exchange}_ASK` }));
|
|
let bid = item.bid.map((price: any) => ({ value: price, name: `${item.exchange}_BID` }));
|
|
let bid = item.bid.map((price: any) => ({ value: price, name: `${item.exchange}_BID` }));
|
|
- series.push({
|
|
|
|
|
|
+ if ((ask.length == 0 || bid.length == 0) && length > 0) {
|
|
|
|
+ ask = Array.from({ length }, () => ({ value: lastSeries[`${item.exchange}_ASK`], name: `${item.exchange}_ASK` }));
|
|
|
|
+ bid = Array.from({ length }, () => ({ value: lastSeries[`${item.exchange}_BID`], name: `${item.exchange}_BID` }));
|
|
|
|
+ }
|
|
|
|
+ newSeries.push({
|
|
name: `${item.exchange}`,
|
|
name: `${item.exchange}`,
|
|
type: "line",
|
|
type: "line",
|
|
|
|
+ silent: true,
|
|
|
|
+ showSymbol: false,
|
|
data: ask,
|
|
data: ask,
|
|
remark: `${item.exchange}_ASK`,
|
|
remark: `${item.exchange}_ASK`,
|
|
smooth: true,
|
|
smooth: true,
|
|
});
|
|
});
|
|
|
|
|
|
- series.push({
|
|
|
|
|
|
+ newSeries.push({
|
|
name: `${item.exchange}`,
|
|
name: `${item.exchange}`,
|
|
type: "line",
|
|
type: "line",
|
|
|
|
+ silent: true,
|
|
|
|
+ showSymbol: false,
|
|
data: bid,
|
|
data: bid,
|
|
remark: `${item.exchange}_BID`,
|
|
remark: `${item.exchange}_BID`,
|
|
smooth: true,
|
|
smooth: true,
|
|
});
|
|
});
|
|
}
|
|
}
|
|
- return series;
|
|
|
|
|
|
+ return newSeries;
|
|
};
|
|
};
|
|
|
|
|
|
const initChart = (data: any) => {
|
|
const initChart = (data: any) => {
|
|
- const chartContainer = document.getElementById("chart");
|
|
|
|
|
|
+ if (myChart.value != null && !myChart.value.isDisposed()) echarts.dispose(myChart.value);
|
|
|
|
+ myChart.value = echarts.init(chartRef.value);
|
|
|
|
+ window.removeEventListener("resize", () => myChart.value.resize());
|
|
|
|
+ window.addEventListener("resize", () => myChart.value.resize());
|
|
|
|
+
|
|
times.value = data.time;
|
|
times.value = data.time;
|
|
series.value = handleSeries(data.values);
|
|
series.value = handleSeries(data.values);
|
|
|
|
|
|
- const isChart = getInstanceByDom(chartContainer!);
|
|
|
|
- if (isChart) myChart.value.dispose();
|
|
|
|
- myChart.value = init(chartContainer);
|
|
|
|
- window.removeEventListener("resize", () => {
|
|
|
|
- myChart.value.resize();
|
|
|
|
- });
|
|
|
|
- window.addEventListener("resize", () => {
|
|
|
|
- myChart.value.resize();
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
const option = {
|
|
const option = {
|
|
title: {
|
|
title: {
|
|
text: "kline_viewer",
|
|
text: "kline_viewer",
|
|
},
|
|
},
|
|
|
|
+ animation: false,
|
|
tooltip: {
|
|
tooltip: {
|
|
trigger: "axis",
|
|
trigger: "axis",
|
|
formatter: (params: any) => {
|
|
formatter: (params: any) => {
|
|
@@ -286,6 +311,8 @@ const initChart = (data: any) => {
|
|
};
|
|
};
|
|
onUnmounted(() => {
|
|
onUnmounted(() => {
|
|
window.removeEventListener("resize", myChart.value.resize());
|
|
window.removeEventListener("resize", myChart.value.resize());
|
|
|
|
+ clearInterval(timer.value);
|
|
|
|
+ myChart.value.dispose();
|
|
});
|
|
});
|
|
</script>
|
|
</script>
|
|
<style lang="scss" scoped>
|
|
<style lang="scss" scoped>
|
|
@@ -302,8 +329,8 @@ onUnmounted(() => {
|
|
.content_top_wp {
|
|
.content_top_wp {
|
|
display: flex;
|
|
display: flex;
|
|
align-items: center;
|
|
align-items: center;
|
|
- justify-content: space-between;
|
|
|
|
.exchange_wp {
|
|
.exchange_wp {
|
|
|
|
+ align-items: center;
|
|
display: flex;
|
|
display: flex;
|
|
.exchange_item {
|
|
.exchange_item {
|
|
cursor: pointer;
|
|
cursor: pointer;
|
|
@@ -354,3 +381,55 @@ onUnmounted(() => {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|
|
</style>
|
|
|
|
+<style lang="scss" scoped>
|
|
|
|
+.custom-form-layout {
|
|
|
|
+ .custom-card-checkbox,
|
|
|
|
+ .custom-checkbox {
|
|
|
|
+ word-break: keep-all;
|
|
|
|
+ display: inline-flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ margin-bottom: 16px;
|
|
|
|
+ padding-right: 20px;
|
|
|
|
+ .label {
|
|
|
|
+ word-break: keep-all;
|
|
|
|
+ display: flex;
|
|
|
|
+ padding-right: 15px;
|
|
|
|
+ }
|
|
|
|
+ .checkbox-group {
|
|
|
|
+ display: flex;
|
|
|
|
+ .checkbox-wp {
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ margin-right: 10px;
|
|
|
|
+ line-height: 38px;
|
|
|
|
+ :deep(.layui-checkbox-label) {
|
|
|
|
+ padding: 0;
|
|
|
|
+ }
|
|
|
|
+ :deep(.layui-form-radio) {
|
|
|
|
+ margin-top: 0;
|
|
|
|
+ }
|
|
|
|
+ :deep(.layui-checkcard) {
|
|
|
|
+ padding: 0 10px;
|
|
|
|
+ width: auto;
|
|
|
|
+ margin: 0 10px 0 0;
|
|
|
|
+ .layui-checkcard-content {
|
|
|
|
+ padding: 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ .checkbox-input {
|
|
|
|
+ width: 40px;
|
|
|
|
+ }
|
|
|
|
+ &:last-child {
|
|
|
|
+ margin-right: 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ .custom-card-checkbox {
|
|
|
|
+ .checkbox-wp {
|
|
|
|
+ padding: 0 20px;
|
|
|
|
+ border: 1px solid #d9d9d9;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+</style>
|