Skip to content

Commit 9bd9f74

Browse files
committed
Improvement - VueUiCandlestick - Expose more data in the svg slot
1 parent 17a35df commit 9bd9f74

File tree

2 files changed

+63
-38
lines changed

2 files changed

+63
-38
lines changed

src/components/vue-ui-candlestick.vue

Lines changed: 62 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,7 @@ const datasetBreakdown = computed(() => {
564564
error({
565565
componentName: 'VueUiCandlestick',
566566
type: 'datasetAttribute',
567-
property: 'last (index 4)',
567+
property: 'close (index 4)',
568568
index: i,
569569
debug: debug.value
570570
})
@@ -587,7 +587,7 @@ const datasetBreakdown = computed(() => {
587587
open: ds[1],
588588
high: ds[2],
589589
low: ds[3],
590-
last: ds[4],
590+
close: ds[4],
591591
volume: ds[5],
592592
}
593593
});
@@ -601,7 +601,7 @@ const minimapSource = computed(() => {
601601
open: ds[1],
602602
high: ds[2],
603603
low: ds[3],
604-
last: ds[4],
604+
close: ds[4],
605605
volume: ds[5],
606606
}
607607
});
@@ -625,33 +625,54 @@ const niceScale = computed(() => {
625625
return calculateNiceScale(extremes.value.min, extremes.value.max, FINAL_CONFIG.value.style.layout.grid.yAxis.dataLabels.steps)
626626
})
627627
628-
function convertToPlot(item, index) {
628+
function convertToPlot(item, index, dpMax = null, dpMin = null) {
629629
return {
630630
...item,
631631
x: checkNaN(drawingArea.value.left + (index * slot.value) + (slot.value / 2)),
632632
y: checkNaN(drawingArea.value.top + (1 - ((item - niceScale.value.min) / (niceScale.value.max - niceScale.value.min))) * drawingArea.value.height),
633-
value: checkNaN(item)
633+
value: checkNaN(item),
634+
isMax: item === dpMax,
635+
isMin: item === dpMin
634636
}
635637
}
636638
637639
const drawableDataset = computed(() => {
640+
const dpMax = {
641+
o: Math.max(...datasetBreakdown.value.map(d => d.open)),
642+
h: Math.max(...datasetBreakdown.value.map(d => d.high)),
643+
l: Math.max(...datasetBreakdown.value.map(d => d.low)),
644+
c: Math.max(...datasetBreakdown.value.map(d => d.low))
645+
};
646+
const dpMin = {
647+
o: Math.min(...datasetBreakdown.value.map(d => d.open)),
648+
h: Math.min(...datasetBreakdown.value.map(d => d.high)),
649+
l: Math.min(...datasetBreakdown.value.map(d => d.low)),
650+
c: Math.min(...datasetBreakdown.value.map(d => d.low))
651+
}
652+
const volumeMax = Math.max(...datasetBreakdown.value.map(d => d.volume));
653+
const volumeMin = Math.min(...datasetBreakdown.value.map(d => d.volume));
654+
638655
return datasetBreakdown.value.map((ds, i) => {
639-
const open = convertToPlot(ds.open, i);
640-
const high = convertToPlot(ds.high, i);
641-
const low = convertToPlot(ds.low, i);
642-
const last = convertToPlot(ds.last, i);
643-
const isBullish = ds.last > ds.open;
656+
const open = convertToPlot(ds.open, i, dpMax.o, dpMin.o);
657+
const high = convertToPlot(ds.high, i, dpMax.h, dpMin.h);
658+
const low = convertToPlot(ds.low, i, dpMax.l, dpMin.l);
659+
const close = convertToPlot(ds.close, i, dpMax.c, dpMin.c);
660+
const isBullish = ds.close > ds.open;
661+
const isMaxVolume = ds.volume === volumeMax;
662+
const isMinVolume = ds.volume === volumeMin;
644663
return {
645664
period: ds.period,
646665
open,
647666
high,
648667
low,
649-
last,
668+
close,
650669
volume: ds.volume,
651670
isBullish,
652-
absoluteIndex: ds.absoluteIndex
671+
absoluteIndex: ds.absoluteIndex,
672+
isMaxVolume,
673+
isMinVolume
653674
}
654-
});
675+
})
655676
});
656677
657678
function convertToMinimapPlot({ item, index,minimapH, unitW }) {
@@ -671,14 +692,14 @@ const minimapDataset = computed(() => {
671692
const open = convertToMinimapPlot({ item: ds.open, index: i, minimapH, unitW });
672693
const high = convertToMinimapPlot({ item: ds.high, index: i, minimapH, unitW });
673694
const low = convertToMinimapPlot({ item: ds.low, index: i, minimapH, unitW });
674-
const last = convertToMinimapPlot({ item: ds.last, index: i, minimapH, unitW });
675-
const isBullish = ds.last > ds.open;
695+
const close = convertToMinimapPlot({ item: ds.close, index: i, minimapH, unitW });
696+
const isBullish = ds.close > ds.open;
676697
return {
677698
period: ds.period,
678699
open,
679700
high,
680701
low,
681-
last,
702+
close,
682703
volume: ds.volume,
683704
isBullish,
684705
absoluteIndex: ds.absoluteIndex
@@ -802,8 +823,8 @@ const slicerLabels = computed(() => {
802823
}
803824
} else {
804825
return {
805-
start: timeLabels.value.find(el => el.absoluteIndex === slicer.value.start).text,
806-
end: timeLabels.value.find(el => el.absoluteIndex === slicer.value.end - 1).text
826+
start: timeLabels.value.find(el => el.absoluteIndex === slicer.value.start)?.text ?? '',
827+
end: timeLabels.value.find(el => el.absoluteIndex === slicer.value.end - 1)?.text ?? ''
807828
}
808829
}
809830
});
@@ -870,8 +891,8 @@ function useTooltip(index, datapoint) {
870891
} else {
871892
if (FINAL_CONFIG.value.style.tooltip.show) {
872893
let html = "";
873-
const { period, open, high, low, last, volume, isBullish } = drawableDataset.value[index];
874-
const { period:tr_period, open:tr_open, high:tr_high, low:tr_low, last:tr_last, volume:tr_volume } = FINAL_CONFIG.value.translations;
894+
const { period, open, high, low, close, volume, isBullish } = drawableDataset.value[index];
895+
const { period:tr_period, open:tr_open, high:tr_high, low:tr_low, close:tr_close, volume:tr_volume } = FINAL_CONFIG.value.translations;
875896
876897
const timeLabel = !FINAL_CONFIG.value.style.layout.grid.xAxis.dataLabels.datetimeFormatter.enable
877898
? period
@@ -911,9 +932,9 @@ function useTooltip(index, datapoint) {
911932
r: FINAL_CONFIG.value.style.tooltip.roundingValue
912933
});
913934
914-
const label_last = dataLabel({
935+
const label_close = dataLabel({
915936
p: FINAL_CONFIG.value.style.tooltip.prefix,
916-
v: last.value,
937+
v: close.value,
917938
s: FINAL_CONFIG.value.style.tooltip.suffix,
918939
r: FINAL_CONFIG.value.style.tooltip.roundingValue
919940
});
@@ -927,12 +948,12 @@ function useTooltip(index, datapoint) {
927948
<line x1="45" x2="50" y1="65" y2="65" stroke="${FINAL_CONFIG.value.style.layout.candle.colors.bullish}" stroke-width="1.5" stroke-linecap="round" />
928949
<line x1="50" x2="55" y1="35" y2="35" stroke="${FINAL_CONFIG.value.style.layout.candle.colors.bullish}" stroke-width="1.5" stroke-linecap="round" />
929950
<text x="38" y="70" text-anchor="end" fill="${FINAL_CONFIG.value.style.tooltip.color}">${label_open}</text>
930-
<text x="62" y="40" text-anchor="start" fill="${FINAL_CONFIG.value.style.tooltip.color}">${label_last}</text>
951+
<text x="62" y="40" text-anchor="start" fill="${FINAL_CONFIG.value.style.tooltip.color}">${label_close}</text>
931952
`: `
932953
<line x1="45" x2="50" y1="35" y2="35" stroke="${FINAL_CONFIG.value.style.layout.candle.colors.bearish}" stroke-width="1.5" stroke-linecap="round" />
933954
<line x1="50" x2="55" y1="65" y2="65" stroke="${FINAL_CONFIG.value.style.layout.candle.colors.bearish}" stroke-width="1.5" stroke-linecap="round" />
934955
<text x="40" y="40" text-anchor="end" fill="${FINAL_CONFIG.value.style.tooltip.color}">${label_open}</text>
935-
<text x="60" y="70" text-anchor="start" fill="${FINAL_CONFIG.value.style.tooltip.color}">${label_last}</text>
956+
<text x="60" y="70" text-anchor="start" fill="${FINAL_CONFIG.value.style.tooltip.color}">${label_close}</text>
936957
`}
937958
<text x="50" y="13" text-anchor="middle" fill="${FINAL_CONFIG.value.style.tooltip.color}">${label_high}</text>
938959
<text x="50" y="97" text-anchor="middle" fill="${FINAL_CONFIG.value.style.tooltip.color}">${label_low}</text>
@@ -944,7 +965,7 @@ function useTooltip(index, datapoint) {
944965
html += `<div>${tr_open}: <b>${label_open}</b></div>`;
945966
html += `<div>${tr_high}: <b>${label_high}</b></div>`;
946967
html += `<div>${tr_low}: <b>${label_low}</b></div>`;
947-
html += `<div>${tr_last}: <b>${label_last}</b></div>`;
968+
html += `<div>${tr_close}: <b>${label_close}</b></div>`;
948969
}
949970
950971
@@ -1024,15 +1045,15 @@ function validSlicerEnd(v) {
10241045
10251046
function generateCsv(callback=null) {
10261047
nextTick(() => {
1027-
const labels = [FINAL_CONFIG.value.translations.period, FINAL_CONFIG.value.translations.open, FINAL_CONFIG.value.translations.high, FINAL_CONFIG.value.translations.low, FINAL_CONFIG.value.translations.last, FINAL_CONFIG.value.translations.volume];
1048+
const labels = [FINAL_CONFIG.value.translations.period, FINAL_CONFIG.value.translations.open, FINAL_CONFIG.value.translations.high, FINAL_CONFIG.value.translations.low, FINAL_CONFIG.value.translations.close, FINAL_CONFIG.value.translations.volume];
10281049
10291050
const values = drawableDataset.value.map((ds, i) => {
10301051
return [
10311052
!FINAL_CONFIG.value.style.layout.grid.xAxis.dataLabels.datetimeFormatter.enable ? ds.period : timeLabels.value[i].text,
10321053
ds.open.value,
10331054
ds.high.value,
10341055
ds.low.value,
1035-
ds.last.value,
1056+
ds.close.value,
10361057
ds.volume
10371058
]
10381059
});
@@ -1069,9 +1090,9 @@ const dataTable = computed(() => {
10691090
s: FINAL_CONFIG.value.table.td.suffix,
10701091
r: FINAL_CONFIG.value.table.td.roundingValue
10711092
});
1072-
const label_last = dataLabel({
1093+
const label_close = dataLabel({
10731094
p: FINAL_CONFIG.value.table.td.prefix,
1074-
v: ds.last.value,
1095+
v: ds.close.value,
10751096
s: FINAL_CONFIG.value.table.td.suffix,
10761097
r: FINAL_CONFIG.value.table.td.roundingValue
10771098
});
@@ -1081,7 +1102,7 @@ const dataTable = computed(() => {
10811102
label_open,
10821103
label_high,
10831104
label_low,
1084-
label_last,
1105+
label_close,
10851106
`${isNaN(ds.volume) ? '-' : ds.volume.toLocaleString()}`,
10861107
]
10871108
});
@@ -1627,8 +1648,8 @@ defineExpose({
16271648
v-for="(candle, i) in drawableDataset"
16281649
:data-cy="`candlestick-rect-underlayer-${i}`"
16291650
:x="candle.open.x - slot / 2 + (slot * (1 - FINAL_CONFIG.style.layout.candle.widthRatio) / 2)"
1630-
:y="candle.isBullish ? candle.last.y : candle.open.y"
1631-
:height="Math.abs(candle.last.y - candle.open.y) <= 0 ? 0.0001 : Math.abs(candle.last.y - candle.open.y)"
1651+
:y="candle.isBullish ? candle.close.y : candle.open.y"
1652+
:height="Math.abs(candle.close.y - candle.open.y) <= 0 ? 0.0001 : Math.abs(candle.close.y - candle.open.y)"
16321653
:width="slot * FINAL_CONFIG.style.layout.candle.widthRatio <= 0 ? 0.0001 : slot * FINAL_CONFIG.style.layout.candle.widthRatio"
16331654
:fill="FINAL_CONFIG.style.layout.candle.gradient.underlayer"
16341655
:rx="FINAL_CONFIG.style.layout.candle.borderRadius"
@@ -1639,8 +1660,8 @@ defineExpose({
16391660
v-for="(candle, i) in drawableDataset"
16401661
:data-cy="`candlestick-rect-${i}`"
16411662
:x="candle.open.x - slot / 2 + (slot * (1 - FINAL_CONFIG.style.layout.candle.widthRatio) / 2)"
1642-
:y="candle.isBullish ? candle.last.y : candle.open.y"
1643-
:height="Math.abs(candle.last.y - candle.open.y) <= 0 ? 0.0001 : Math.abs(candle.last.y - candle.open.y)"
1663+
:y="candle.isBullish ? candle.close.y : candle.open.y"
1664+
:height="Math.abs(candle.close.y - candle.open.y) <= 0 ? 0.0001 : Math.abs(candle.close.y - candle.open.y)"
16441665
:width="slot * FINAL_CONFIG.style.layout.candle.widthRatio <= 0 ? 0.0001 : slot * FINAL_CONFIG.style.layout.candle.widthRatio"
16451666
:fill="candle.isBullish ? FINAL_CONFIG.style.layout.candle.gradient.show ? `url(#bullish_gradient_${uid})` : FINAL_CONFIG.style.layout.candle.colors.bullish : FINAL_CONFIG.style.layout.candle.gradient.show ? `url(#bearish_gradient_${uid})` : FINAL_CONFIG.style.layout.candle.colors.bearish"
16461667
:rx="FINAL_CONFIG.style.layout.candle.borderRadius"
@@ -1656,7 +1677,7 @@ defineExpose({
16561677
<template v-if="FINAL_CONFIG.type === 'ohlc'">
16571678
<g v-for="(dp, i) in drawableDataset">
16581679
<path
1659-
:d="`M ${dp.high.x},${dp.high.y} ${dp.low.x},${dp.low.y} M${dp.open.x - Math.min(6, slot / 3)},${dp.open.y} ${dp.open.x},${dp.open.y} M${dp.last.x},${dp.last.y} ${dp.last.x + Math.min(6, slot / 3)},${dp.last.y}`"
1680+
:d="`M ${dp.high.x},${dp.high.y} ${dp.low.x},${dp.low.y} M${dp.open.x - Math.min(6, slot / 3)},${dp.open.y} ${dp.open.x},${dp.open.y} M${dp.close.x},${dp.close.y} ${dp.close.x + Math.min(6, slot / 3)},${dp.close.y}`"
16601681
:stroke="dp.isBullish ? FINAL_CONFIG.style.layout.candle.colors.bullish : FINAL_CONFIG.style.layout.candle.colors.bearish"
16611682
:stroke-width="1"
16621683
/>
@@ -1688,7 +1709,11 @@ defineExpose({
16881709
:data-end="slicer.end"
16891710
/>
16901711
1691-
<slot name="svg" :svg="svg"/>
1712+
<slot name="svg" :svg="{
1713+
...svg,
1714+
data: drawableDataset,
1715+
drawingArea
1716+
}"/>
16921717
</svg>
16931718
16941719
<div v-if="$slots.watermark" class="vue-data-ui-watermark">
@@ -1761,7 +1786,7 @@ defineExpose({
17611786
}"
17621787
/>
17631788
<path
1764-
:d="`M ${dp.open.x},${dp.open.y} ${dp.last.x},${dp.last.y}`"
1789+
:d="`M ${dp.open.x},${dp.open.y} ${dp.close.x},${dp.close.y}`"
17651790
:stroke="dp.isBullish ? FINAL_CONFIG.style.layout.candle.colors.bullish : FINAL_CONFIG.style.layout.candle.colors.bearish"
17661791
:stroke-width="Math.min(6, unitW / 1.5)"
17671792
:style="{

src/useConfig.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2436,7 +2436,7 @@ export function useConfig() {
24362436
open: "Open",
24372437
high: "High",
24382438
low: "Low",
2439-
last: "Last",
2439+
last: "Close",
24402440
volume: "Volume"
24412441
},
24422442
userOptions: USER_OPTIONS({

0 commit comments

Comments
 (0)