차트 정의 완료

This commit is contained in:
2025-08-24 18:29:12 +09:00
parent 04131e7506
commit 7cf6f367ea
6 changed files with 53 additions and 21734 deletions

View File

@@ -4,7 +4,7 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Vue + TS</title> <title>Chart</title>
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>

14257
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -16,9 +16,9 @@ import {calculateMACD, calculateEMA, calculateBollingerBands} from "./utils/mete
* @param {Boolean} ohlc Whether generated dat should include open, high, low, and close values * @param {Boolean} ohlc Whether generated dat should include open, high, low, and close values
* @returns {Array} sample data * @returns {Array} sample data
*/ */
let socket; let socket;
const lazyLock = ref(false) const lazyLock = ref(false)
const positionData = ref('')
const contract = ref('BTC_USDT') const contract = ref('BTC_USDT')
const time = ref('15m') const time = ref('15m')
@@ -193,6 +193,13 @@ const curToUnix = (() => {
return Math.floor(new Date().getTime() / 1000); return Math.floor(new Date().getTime() / 1000);
}) })
const epochToString = (epo) => {
const cu = new Date(epo)
return cu.getFullYear() + '-' + cu.getMonth().toString().padStart(2, '0') + '-' +
cu.getDate().toString().padStart(2, '0') + ' ' + cu.getHours().toString().padStart(2, '0') + ':' +
cu.getMinutes().toString().padStart(2, '0') + ':' + cu.getSeconds().toString().padStart(2, '0');
}
const colorsTypeMap = { const colorsTypeMap = {
area: [ area: [
@@ -224,6 +231,16 @@ const colorsTypeMap = {
line: [['color', 1]], line: [['color', 1]],
}; };
const mouseMove = (data) => {
positionData.value = `
<span style="color:red; padding-right:3px;">O</span>${data.open}
<span style="color:red; padding-left:5px; padding-right:3px;">C</span>${data.close}
<span style="color:red; padding-left:5px; padding-right:3px;">L</span>${data.low}
<span style="color:red; padding-left:5px; padding-right:3px;">H</span>${data.high}
<span style="color:red; padding-left:5px; padding-right:3px;">T</span>${epochToString(data.time*1000)}
`;
}
watch(contract, newVal => { watch(contract, newVal => {
distroy() distroy()
console.log(newVal); console.log(newVal);
@@ -235,6 +252,7 @@ watch(time, newVal => {
console.log(newVal); console.log(newVal);
init(contract.value, newVal) init(contract.value, newVal)
}) })
</script> </script>
<template> <template>
@@ -297,13 +315,28 @@ watch(time, newVal => {
:upper-bb-options="upperBbOptions" :upper-bb-options="upperBbOptions"
:lazyLock="lazyLock" :lazyLock="lazyLock"
@lazyLoad="lazyLoad" @lazyLoad="lazyLoad"
@mouseMove="mouseMove"
ref="lwChart" ref="lwChart"
/> />
<div class="ohlc-info" v-html="positionData"></div>
</div> </div>
</div> </div>
</template> </template>
<style scoped> <style scoped lang="scss">
.chart-container { .chart-container {
height: calc(100% - 3.2em); height: calc(100% - 3.2em);
} }
.ohlc-info {
position: absolute;
top: 20px;
left: 10px;
font-size: 12px;
color: #333;
background: rgba(255, 255, 255, 0.8);
padding: 5px;
border-radius: 4px;
z-index: 1000;
}
</style> </style>

View File

@@ -79,7 +79,7 @@ const props = defineProps({
}, },
}); });
const emits = defineEmits(['lazyLoad']) const emits = defineEmits(['lazyLoad', 'mouseMove'])
function getChartSeriesDefinition(type) { function getChartSeriesDefinition(type) {
switch (type.toLowerCase()) { switch (type.toLowerCase()) {
@@ -204,6 +204,7 @@ onMounted(() => {
} }
chart.timeScale().subscribeVisibleLogicalRangeChange(onVisibleLogicalRangeChanged); chart.timeScale().subscribeVisibleLogicalRangeChange(onVisibleLogicalRangeChanged);
chart.subscribeCrosshairMove(onCrosshairMove)
}); });
function onVisibleLogicalRangeChanged(newVisibleLogicalRange) { function onVisibleLogicalRangeChanged(newVisibleLogicalRange) {
@@ -216,6 +217,17 @@ function onVisibleLogicalRangeChanged(newVisibleLogicalRange) {
} }
} }
function onCrosshairMove(param) {
if (param.point === null || param.time === undefined) {
return;
}
emits('mouseMove', param.seriesData.get(candlestick))
//
// // 현재 포인터 아래의 캔들 데이터 가져오기
// const data = param.seriesData.get(candleSeries);
// console.log(data)
}
onUnmounted(() => { onUnmounted(() => {
if (chart) { if (chart) {

View File

@@ -2,9 +2,13 @@ import { createApp } from 'vue'
import './style.css' import './style.css'
import App from './App.vue' import App from './App.vue'
import vuetify from './plugins/vuetify' import vuetify from './plugins/vuetify'
import {createPinia} from "pinia";
const app = createApp(App) const app = createApp(App)
app.use(vuetify) app.use(vuetify)
const pinia = createPinia()
app.use(pinia)
app.mount('#app') app.mount('#app')

7473
yarn.lock

File diff suppressed because it is too large Load Diff