From c42857f46e7c6fa6f8bb0b75f399707789c4ab72 Mon Sep 17 00:00:00 2001
From: lxf <1371462558@qq.com>
Date: Sat, 21 Jun 2025 16:47:27 +0800
Subject: [PATCH] k线添加网格
---
src/components/kline-charts/index.vue | 319 ++++++++++++++++++++++++++++++++++++-----------------
1 files changed, 216 insertions(+), 103 deletions(-)
diff --git a/src/components/kline-charts/index.vue b/src/components/kline-charts/index.vue
index a5c96a0..9d891b4 100644
--- a/src/components/kline-charts/index.vue
+++ b/src/components/kline-charts/index.vue
@@ -1,196 +1,309 @@
<template>
<div class="kline-charts">
- <ul class="flex px-32 pb-20 box-border justify-between text-grey fontStyle font-26"
- style="border-bottom:1px solid rgba(68,75,88,0.2);">
- <li v-for="item in timeList" :key="item.id" class="mr-10" :class="{ 'textColor': item.id === timeValue.id }"
- @click="choiceTime(item)">{{ item.text }}</li>
+ <ul
+ class="flex px-32 pb-20 box-border justify-between text-grey fontStyle font-26"
+ style="border-bottom: 1px solid rgba(68, 75, 88, 0.2)"
+ >
+ <li
+ v-for="item in timeList"
+ :key="item.id"
+ class="mr-10"
+ :class="{ textColor: item.id === timeValue.id }"
+ @click="choiceTime(item)"
+ >
+ {{ item.text }}
+ </li>
</ul>
<div class="relative">
<div id="kline" class="h-828"></div>
<div
- class="flex justify-center items-center text-center text-grey absolute left-0 top-0 w-full h-full z-10 mainBackground"
- v-if="chartLoading">
+ class="flex justify-center items-center text-center text-grey absolute left-0 top-0 w-full h-full z-10 mainBackground"
+ v-if="chartLoading"
+ >
<van-loading type="spinner"></van-loading>
</div>
</div>
- <ul class="flex px-32 py-20 box-border justify-between text-grey font-26" v-if="showBottom"
- style="border-top:1px solid rgba(68,75,88,0.2);">
- <li v-for="item in subTechnicalIndicatorTypes" :key="item" class="mr-20"
- :class="{ 'textColor': typeValue === item }" @click="choiceType(item)">{{ item }}</li>
+ <ul
+ class="flex px-32 py-20 box-border justify-between text-grey font-26"
+ v-if="showBottom"
+ style="border-top: 1px solid rgba(68, 75, 88, 0.2)"
+ >
+ <li
+ v-for="item in subTechnicalIndicatorTypes"
+ :key="item"
+ class="mr-20"
+ :class="{ textColor: typeValue === item }"
+ @click="choiceType(item)"
+ >
+ {{ item }}
+ </li>
</ul>
</div>
</template>
<script>
-import { init, dispose } from 'klinecharts'
-let chart = null
-import { _getKline } from '@/API/trade.api'
-import config from './config'
-import { Loading } from 'vant';
+import { init, dispose } from "klinecharts";
+let chart = null;
+import { _getKline } from "@/API/trade.api";
+import config from "./config";
+import { Loading } from "vant";
import { scientificNotationToString } from "@/utils/utis";
export default {
- name: 'KlineCharts',
+ name: "KlineCharts",
data() {
return {
// symbol: 'btc',
- dealInfo: {},//交易对信息
+ dealInfo: {}, //交易对信息
timeValue: {}, // 当前k线周期
- subTechnicalIndicatorTypes: ['MA', 'EMA', 'BOLL', 'VOL', 'MACD', 'KDJ', 'RSI'],
- typeValue: 'VOL',//图形类型
- klinecharts: null,//K线图实例
+ subTechnicalIndicatorTypes: [
+ "MA",
+ "EMA",
+ "BOLL",
+ "VOL",
+ "MACD",
+ "KDJ",
+ "RSI",
+ ],
+ typeValue: "VOL", //图形类型
+ klinecharts: null, //K线图实例
chart: null,
// resolution: '1',//分辨率
// lang: 'en', //语言
chartLoading: true, //加载动画
- paneId: '',
+ paneId: "",
chartData: [], // 图表数据
- timer: null
- }
+ timer: null,
+ grid: {
+ show: true,
+ horizontal: {
+ show: true,
+ size: 0.1,
+ color: "#f0f0f0",
+ style: "dashed",
+ dashedValue: [1, 2],
+ },
+ vertical: {
+ show: true,
+ size: 0.1,
+ color: "#f0f0f0",
+ style: "dashed",
+ dashedValue: [1, 2],
+ },
+ },
+ };
},
computed: {
timeList() {
return [
- { id: '1min', time: '1min', text: this.$t('分时'), ts: 1 * 60 * 1000 },
- { id: '1mins', time: '1min', text: '1' + this.$t('分'), ts: 1 * 60 * 1000 },
- { id: '5min', time: '5min', text: '5' + this.$t('分'), ts: 5 * 60 * 1000 },
- { id: '15min', time: '15min', text: '15' + this.$t('分'), ts: 15 * 60 * 1000 },
- { id: '30min', time: '30min', text: '30' + this.$t('分'), ts: 30 * 60 * 1000 },
- { id: '60min', time: '60min', text: '1' + this.$t('小时'), ts: 60 * 60 * 1000 },
- { id: '4hour', time: '4hour', text: '4' + this.$t('小时'), ts: 4 * 60 * 60 * 1000 },
- { id: '1day', time: '1day', text: '1' + this.$t('天'), ts: 24 * 60 * 60 * 1000 },
- { id: '1week', time: '1week', text: '1' + this.$t('周'), ts: 7 * 24 * 60 * 60 * 1000 },
- { id: '1mon', time: '1mon', text: '1' + this.$t('月'), ts: 30 * 24 * 60 * 60 * 1000 }
- ]//时间列表
- }
+ { id: "1min", time: "1min", text: this.$t("分时"), ts: 1 * 60 * 1000 },
+ {
+ id: "1mins",
+ time: "1min",
+ text: "1" + this.$t("分"),
+ ts: 1 * 60 * 1000,
+ },
+ {
+ id: "5min",
+ time: "5min",
+ text: "5" + this.$t("分"),
+ ts: 5 * 60 * 1000,
+ },
+ {
+ id: "15min",
+ time: "15min",
+ text: "15" + this.$t("分"),
+ ts: 15 * 60 * 1000,
+ },
+ {
+ id: "30min",
+ time: "30min",
+ text: "30" + this.$t("分"),
+ ts: 30 * 60 * 1000,
+ },
+ {
+ id: "60min",
+ time: "60min",
+ text: "1" + this.$t("小时"),
+ ts: 60 * 60 * 1000,
+ },
+ {
+ id: "4hour",
+ time: "4hour",
+ text: "4" + this.$t("小时"),
+ ts: 4 * 60 * 60 * 1000,
+ },
+ {
+ id: "1day",
+ time: "1day",
+ text: "1" + this.$t("天"),
+ ts: 24 * 60 * 60 * 1000,
+ },
+ {
+ id: "1week",
+ time: "1week",
+ text: "1" + this.$t("周"),
+ ts: 7 * 24 * 60 * 60 * 1000,
+ },
+ {
+ id: "1mon",
+ time: "1mon",
+ text: "1" + this.$t("月"),
+ ts: 30 * 24 * 60 * 60 * 1000,
+ },
+ ]; //时间列表
+ },
},
components: {
- [Loading.name]: Loading
+ [Loading.name]: Loading,
},
props: {
symbol: {
type: String,
- default: ''
+ default: "",
},
updateKey: {
type: Number,
- default: 0
+ default: 0,
},
updateData: {
type: Object,
default() {
- return {}
- }
+ return {};
+ },
},
showBottom: {
type: Boolean,
- default: true
+ default: true,
},
isChangeLine: {
type: Boolean,
- default: false
+ default: false,
},
},
mounted() {
- this.initData()
+ this.initData();
},
beforeDestroy() {
- this.clearTimer()
- dispose('kline')
+ this.clearTimer();
+ dispose("kline");
},
watch: {
isChangeLine(val) {
- this.clearTimer()
- this.fetchData()
+ this.clearTimer();
+ this.fetchData();
},
- updateKey() { // 更新charts
- const dataList = chart.getDataList()
- const lastData = dataList[dataList.length - 1]
- const nowData = this.updateData
- const timeValue = this.timeValue
+ updateKey() {
+ // 更新charts
+ const dataList = chart.getDataList();
+ const lastData = dataList[dataList.length - 1];
+ const nowData = this.updateData;
+ const timeValue = this.timeValue;
const newData = {
close: nowData.close / 1,
current_time: lastData.current_time,
- high: lastData.high > nowData.close / 1 ? lastData.high : (nowData.close / 1),
+ high:
+ lastData.high > nowData.close / 1 ? lastData.high : nowData.close / 1,
// high: lastData.high,
line: timeValue.id,
- low: lastData.low < nowData.close / 1 ? lastData.low : (nowData.close / 1),
+ low:
+ lastData.low < nowData.close / 1 ? lastData.low : nowData.close / 1,
// low: lastData.low,
open: lastData.open,
symbol: lastData.symbol,
ts: lastData.ts, //
- timestamp: (nowData.ts - lastData.ts) < timeValue.ts ? lastData.ts : (lastData.ts + timeValue.ts),
- volume: lastData.volume / 1
- }
+ timestamp:
+ nowData.ts - lastData.ts < timeValue.ts
+ ? lastData.ts
+ : lastData.ts + timeValue.ts,
+ volume: lastData.volume / 1,
+ };
this.$nextTick(() => {
- this.setChartType()
- chart.updateData(newData)
- })
- }
+ this.setChartType();
+ chart.updateData(newData);
+ });
+ },
},
methods: {
initData() {
- this.timeValue = this.timeList[0]
- chart = init('kline', config);
- chart.setOffsetRightSpace(25)
- chart.setDataSpace(10)
- chart.setPriceVolumePrecision(4, 2)
- chart.createTechnicalIndicator('MA', false, { id: 'candle_pane' });
- this.paneId = chart.createTechnicalIndicator('VOL');
- this.fetchData()
+ this.timeValue = this.timeList[0];
+ chart = init("kline", config);
+ chart.setOffsetRightSpace(25);
+ chart.setDataSpace(10);
+ chart.setPriceVolumePrecision(4, 2);
+ chart.createTechnicalIndicator("MA", false, { id: "candle_pane" });
+ chart.getStyleOptions().grid = this.grid;
+ chart.setStyleOptions({
+ grid: this.grid,
+ // candle: {
+ // upColor: "#FF0000",
+ // downColor: "#00FF00",
+ // borderUpColor: "#FF0000",
+ // borderDownColor: "#00FF00",
+ // wickUpColor: "#FF0000",
+ // wickDownColor: "#00FF00",
+ // },
+ });
+ this.paneId = chart.createTechnicalIndicator("VOL");
+ this.fetchData();
},
- fetchData(time) { // 获取数据
- this.chartLoading = true
+ fetchData(time) {
+ // 获取数据
+ this.chartLoading = true;
this.timer = setInterval(() => {
- _getKline(this.symbol, this.timeValue.time || time).then(data => {
- this.chartLoading = false
- data.map(item => {
- item.timestamp = item.ts
- })
+ _getKline(this.symbol, this.timeValue.time || time).then((data) => {
+ this.chartLoading = false;
+ data.map((item) => {
+ item.timestamp = item.ts;
+ });
//科学计数法时转成字符串
- let str = data[0] ? scientificNotationToString(data[data.length - 1].close.toString()) : ''
- let length = 2
- if (str.indexOf('.') != -1) {
- length = str.split('.')[1].length
+ let str = data[0]
+ ? scientificNotationToString(data[data.length - 1].close.toString())
+ : "";
+ let length = 2;
+ if (str.indexOf(".") != -1) {
+ length = str.split(".")[1].length;
}
//let length = data[0] ? data[0].close.toString().split('.')[1].length : 4
- chart.setPriceVolumePrecision(length, 2)
- this.setChartType()
+ chart.setPriceVolumePrecision(length, 2);
+ this.setChartType();
chart.applyNewData(data);
- this.$emit('updataLine', false)
- })
+ this.$emit("updataLine", false);
+ });
}, 1000);
},
setChartType() {
- let type = 'area'
- if (this.timeValue.id === '1min') {
- type = 'area'
+ let type = "area";
+ if (this.timeValue.id === "1min") {
+ type = "area";
} else {
- type = 'candle_solid'
+ type = "candle_solid";
}
chart.setStyleOptions({
candle: {
- type
- }
- })
+ type,
+ },
+ });
},
- choiceTime(value) { // 选择周期
- this.timeValue = value
- this.clearTimer()
- this.fetchData()
+ choiceTime(value) {
+ // 选择周期
+ this.timeValue = value;
+ this.clearTimer();
+ this.fetchData();
},
- choiceType(type) { // 选择副线
- this.typeValue = type
- chart.createTechnicalIndicator(type, false, { id: this.paneId })
+ choiceType(type) {
+ // 选择副线
+ this.typeValue = type;
+ chart.createTechnicalIndicator(type, false, { id: this.paneId });
},
clearTimer() {
- clearInterval(this.timer)
- this.timer = null
+ clearInterval(this.timer);
+ this.timer = null;
},
},
deactivated() {
- this.clearTimer()
- }
-}
+ this.clearTimer();
+ },
+};
</script>
<style lang="scss" scoped>
.textColor {
--
Gitblit v1.9.3