차트 정의 완료

This commit is contained in:
2025-08-24 16:23:27 +09:00
parent 44f70df8c2
commit 04131e7506
11 changed files with 537 additions and 126 deletions

View File

@@ -26,6 +26,16 @@ const props = defineProps({
type: Array,
required: true,
},
ema: {
type: Array,
required: true,
},
macd: {
type: Object,
},
bb: {
type: Object,
},
autosize: {
default: true,
type: Boolean,
@@ -33,7 +43,28 @@ const props = defineProps({
chartOptions: {
type: Object,
},
seriesOptions: {
emaOptions: {
type: Object,
},
candleOptions: {
type: Object,
},
macdLineOptions: {
type: Object,
},
macdSignalOptions: {
type: Object,
},
macdHistogramOptions: {
type: Object,
},
upperBbOptions: {
type: Object,
},
middleBbOptions: {
type: Object,
},
lowerBbOptions: {
type: Object,
},
timeScaleOptions: {
@@ -42,8 +73,14 @@ const props = defineProps({
priceScaleOptions: {
type: Object,
},
lazyLock: {
type: Boolean,
default: false,
},
});
const emits = defineEmits(['lazyLoad'])
function getChartSeriesDefinition(type) {
switch (type.toLowerCase()) {
case 'line':
@@ -64,9 +101,20 @@ function getChartSeriesDefinition(type) {
// Lightweight Charts™ instances are stored as normal JS variables
// If you need to use a ref then it is recommended that you use `shallowRef` instead
let series;
let emaLine;
let candlestick;
let chart;
let macdLine;
let macdSignalLine;
let macdHistogram;
let mainPane;
let macdPane;
let upperBb;
let middleBb;
let lowerBb;
const chartContainer = ref();
const fitContent = () => {
@@ -78,7 +126,7 @@ const getChart = () => {
return chart;
};
defineExpose({ fitContent, getChart });
defineExpose({fitContent, getChart});
// Auto resizes the chart when the browser window is resized.
const resizeHandler = () => {
@@ -89,15 +137,56 @@ const resizeHandler = () => {
// Creates the chart series and sets the data.
const addSeriesAndData = props => {
const seriesDefinition = getChartSeriesDefinition(props.type);
series = chart.addSeries(seriesDefinition, props.seriesOptions);
series.setData(props.data);
const candleStickDefinition = getChartSeriesDefinition(props.type);
candlestick = chart.addSeries(candleStickDefinition, props.candleOptions);
let oldT = 0;
let list = []
props.data.forEach(item => {
if (item.t !== oldT) {
list.push({
time: Number(item.t),
open: Number(item.o),
high: Number(item.h),
low: Number(item.l),
close: Number(item.c),
volume: Number(item.v),
})
}
oldT = item.t
})
candlestick.setData(list);
const seriesDefinition = getChartSeriesDefinition('line')
emaLine = chart.addSeries(seriesDefinition, props.emaOptions)
emaLine.setData(props.ema)
console.log(Object.keys(props.macd).length)
macdLine = macdPane.addSeries(seriesDefinition, props.macdLineOptions)
macdSignalLine = macdPane.addSeries(seriesDefinition, props.macdSignalOptions)
macdHistogram = macdPane.addSeries(getChartSeriesDefinition('histogram'), props.macdHistogramOptions)
if(Object.keys(props.macd).length) {
macdLine.setData(props.macd.m)
macdHistogram.setData(props.macd.h)
macdSignalLine.setData(props.macd.s)
}
upperBb = chart.addSeries(seriesDefinition, props.upperBbOptions);
middleBb = chart.addSeries(seriesDefinition, props.middleBbOptions);
lowerBb = chart.addSeries(seriesDefinition, props.lowerBbOptions);
if(Object.keys(props.macd).length) {
upperBb.setData(props.bb.u);
middleBb.setData(props.bb.m);
lowerBb.setData(props.bb.l);
}
// console.log(3)
};
onMounted(() => {
// Create the Lightweight Charts Instance using the container ref.
chart = createChart(chartContainer.value, props.chartOptions);
console.log(props)
macdPane = chart.addPane();
macdPane.setStretchFactor(0.5)
addSeriesAndData(props);
if (props.priceScaleOptions) {
@@ -113,15 +202,28 @@ onMounted(() => {
if (props.autosize) {
window.addEventListener('resize', resizeHandler);
}
chart.timeScale().subscribeVisibleLogicalRangeChange(onVisibleLogicalRangeChanged);
});
function onVisibleLogicalRangeChanged(newVisibleLogicalRange) {
const barsInfo = candlestick.barsInLogicalRange(newVisibleLogicalRange);
// if there less than 50 bars to the left of the visible area
if (barsInfo !== null && barsInfo.barsBefore < 500 && !props.lazyLock) {
// try to load additional historical data and prepend it to the series data
emits('lazyLoad', props.data[0].t - 5000);
}
}
onUnmounted(() => {
if (chart) {
chart.remove();
chart = null;
}
if (series) {
series = null;
if (candlestick) {
candlestick = null;
}
window.removeEventListener('resize', resizeHandler);
});
@@ -151,8 +253,8 @@ watch(
watch(
() => props.type,
newType => {
if (series && chart) {
chart.removeSeries(series);
if (candlestick && chart) {
chart.removeSeries(candlestick);
}
addSeriesAndData(props);
}
@@ -161,8 +263,53 @@ watch(
watch(
() => props.data,
newData => {
if (!series) return;
series.setData(newData);
if (!candlestick) return;
let oldT = 0;
let list = []
newData.forEach(item => {
if (item.t !== oldT) {
list.push({
time: item.t,
open: Number(item.o),
high: Number(item.h),
low: Number(item.l),
close: Number(item.c),
volume: Number(item.v),
})
}
oldT = item.t
})
candlestick.setData(list);
}
);
watch(
() => props.ema,
newData => {
if (!emaLine) return;
emaLine.setData(newData);
}
);
watch(
() => props.macd,
newData => {
if (!macdLine || !macdHistogram || !macdSignalLine) return;
macdLine.setData(newData.m);
macdHistogram.setData(newData.h);
macdSignalLine.setData(newData.s);
}
);
watch(
() => props.bb,
newData => {
if (!upperBb || !middleBb || !lowerBb) return;
upperBb.setData(newData.u);
middleBb.setData(newData.m);
lowerBb.setData(newData.l);
}
);
@@ -175,10 +322,42 @@ watch(
);
watch(
() => props.seriesOptions,
() => props.candleOptions,
newOptions => {
if (!series) return;
series.applyOptions(newOptions);
if (!candlestick) return;
candlestick.applyOptions(newOptions);
}
);
watch(
() => props.emaOptions,
newOptions => {
if (!emaLine) return;
emaLine.applyOptions(newOptions);
}
);
watch(
() => props.macdLineOptions,
newOptions => {
if (!macdLine) return;
macdLine.applyOptions(newOptions);
}
);
watch(
() => props.macdSignalOptions,
newOptions => {
if (!macdSignalLine) return;
macdSignalLine.applyOptions(newOptions);
}
);
watch(
() => props.macdHistogramOptions,
newOptions => {
if (!macdHistogram) return;
macdHistogram.applyOptions(newOptions);
}
);