@@ -11,23 +11,45 @@ import { VueUiCandlestick as VueUiCandlestickTreshaken } from "vue-data-ui/vue-u
1111
1212const dataset = ref ([]);
1313
14+ function generateRandomCandlestickData ({
15+ count = 12 ,
16+ startDate = Date .UTC (2024 , 0 , 1 ), // starting date (Jan 1, 2024)
17+ interval = 30 * 24 * 60 * 60 * 1000 , // 1 month in ms
18+ startPrice = 100 ,
19+ volatility = 0.2 // 20% volatility
20+ } = {}) {
21+ const data = [];
22+ let lastClose = startPrice;
23+
24+ for (let i = 0 ; i < count; i++ ) {
25+ const timestamp = startDate + i * interval;
26+
27+ // simulate price movement
28+ const changePercent = (Math .random () - 0.5 ) * volatility;
29+ const open = lastClose;
30+ const close = open * (1 + changePercent);
31+ const high = Math .max (open, close) * (1 + Math .random () * volatility);
32+ const low = Math .min (open, close) * (1 - Math .random () * volatility);
33+ const volume = Math .round (1000 + Math .random () * 9000 );
34+
35+ data .push ([
36+ timestamp,
37+ Math .round (open),
38+ Math .round (high),
39+ Math .round (low),
40+ Math .round (close),
41+ volume
42+ ]);
43+
44+ lastClose = close;
45+ }
46+ return data;
47+ }
48+
1449onMounted (() => {
1550 dataset .value = undefined ;
1651 setTimeout (() => {
17- dataset .value = [
18- [1704067200000 , 10 , 20 , 2 , 10 , 30 ],
19- [1706745600000 , 10 , 30 , 5 , 20 , 50 ],
20- [1709251200000 , 20 , 50 , 10 , 30 , 80 ],
21- [1711929600000 , 30 , 80 , 20 , 50 , 130 ],
22- [1714521600000 , 50 , 130 , 30 , 100 , 210 ],
23- [1717200000000 , 80 , 210 , 50 , 150 , 340 ],
24- [1719792000000 , 130 , 340 , 80 , 280 , 550 ],
25- [1722470400000 , 210 , 550 , 130 , 50 , 890 ],
26- [1725148800000 , 340 , 890 , 210 , 750 , 1440 ],
27- [1727740800000 , 550 , 1440 , 340 , 1230 , 2330 ],
28- [1730419200000 , 890 , 2330 , 550 , 1950 , 3770 ],
29- [1733011200000 , 1440 , 3770 , 890 , 3200 , 5100 ]
30- ]
52+ dataset .value = generateRandomCandlestickData ({ count: 100 })
3153 }, 2000 )
3254})
3355
@@ -65,6 +87,7 @@ function alterDataset() {
6587}
6688
6789const model = ref ([
90+ { key: ' type' , def: ' ohlc' , type: ' select' , options: [' ohlc' , ' candlestick' ]},
6891 { key: ' loading' , def: false , type: ' checkbox' },
6992 { key: ' debug' , def: false , type: ' checkbox' },
7093 { key: ' responsive' , def: false , type: ' checkbox' },
@@ -91,14 +114,25 @@ const model = ref([
91114 { key: ' style.height' , def: 316 , type: ' number' , min: 100 , max: 1000 },
92115 { key: ' style.width' , def: 512 , type: ' number' , min: 100 , max: 1000 },
93116 { key: ' style.layout.padding.top' , def: 0 , type: ' number' , min: 0 , max: 100 },
94- { key: ' style.layout.padding.right' , def: 0 , type: ' number' , min: 0 , max: 100 },
117+ { key: ' style.layout.padding.right' , def: 12 , type: ' number' , min: 0 , max: 100 },
95118 { key: ' style.layout.padding.bottom' , def: 0 , type: ' number' , min: 0 , max: 100 },
96119 { key: ' style.layout.padding.left' , def: 0 , type: ' number' , min: 0 , max: 100 },
97120 { key: ' style.layout.selector.color' , def: ' #1A1A1A' , type: ' color' },
98121 { key: ' style.layout.selector.opacity' , def: 10 , type: ' range' , min: 0 , max: 100 },
99122 { key: ' style.layout.grid.show' , def: true , type: ' checkbox' },
100- { key: ' style.layout.grid.stroke' , def: ' #e1e5e8' , type: ' color' },
101- { key: ' style.layout.grid.strokeWidth' , def: 0.5 , type: ' range' , min: 0 , max: 12 , step: 0.5 },
123+ { key: ' style.layout.grid.stroke' , def: ' #CCCCCC' , type: ' color' },
124+ { key: ' style.layout.grid.strokeWidth' , def: 1 , type: ' range' , min: 0 , max: 12 , step: 0.5 },
125+
126+ { key: ' style.layout.grid.horizontalLines.show' , def: true , type: ' checkbox' },
127+ { key: ' style.layout.grid.horizontalLines.strokeDasharray' , def: 3 , type: ' number' , min: 0 , max: 12 },
128+ { key: ' style.layout.grid.horizontalLines.stroke' , def: ' #FF0000' , type: ' color' },
129+ { key: ' style.layout.grid.horizontalLines.strokeWidth' , def: 0.5 , type: ' number' , min: 0 , max: 12 , step: 0.1 },
130+
131+ { key: ' style.layout.grid.verticalLines.show' , def: true , type: ' checkbox' },
132+ { key: ' style.layout.grid.verticalLines.strokeDasharray' , def: 3 , type: ' number' , min: 0 , max: 12 },
133+ { key: ' style.layout.grid.verticalLines.stroke' , def: ' #0000FF' , type: ' color' },
134+ { key: ' style.layout.grid.verticalLines.strokeWidth' , def: 0.5 , type: ' number' , min: 0 , max: 12 , step: 0.1 },
135+
102136 { key: ' style.layout.grid.xAxis.dataLabels.show' , def: true , type: ' checkbox' },
103137 { key: ' style.layout.grid.xAxis.dataLabels.fontSize' , def: 10 , type: ' number' , min: 4 , max: 12 },
104138 { key: ' style.layout.grid.xAxis.dataLabels.color' , def: ' #1A1A1A' , type: ' color' },
@@ -120,7 +154,7 @@ const model = ref([
120154 { key: ' style.layout.grid.yAxis.scale.max' , def: null , type: ' number' , min: 0 , max: 10000 },
121155
122156 { key: ' style.layout.wick.stroke' , def: ' #1A1A1A' , type: ' color' },
123- { key: ' style.layout.wick.strokeWidth' , def: 3 , type: ' number' , min: 0 , max: 12 , step: 0.5 },
157+ { key: ' style.layout.wick.strokeWidth' , def: 0.5 , type: ' number' , min: 0 , max: 12 , step: 0.5 },
124158 { key: ' style.layout.wick.extremity.shape' , def: ' line' , type: ' select' , options: [' line' , ' circle' ]},
125159 { key: ' style.layout.wick.extremity.size' , def: ' auto' , type: ' select' , options: [' auto' , 5 , 10 , 20 , 40 ]},
126160 { key: ' style.layout.wick.extremity.color' , def: ' #1A1A1A' , type: ' color' },
@@ -145,6 +179,8 @@ const model = ref([
145179 { key: ' style.zoom.enableSelectionDrag' , def: true , type: ' chexkbox' },
146180 { key: ' style.zoom.focusOnDrag' , def: true , type: ' checkbox' },
147181 { key: ' style.zoom.focusRangeRatio' , def: 0.2 , type: ' number' , min: 0.1 , max: 0.9 , step: 0.1 },
182+ { key: ' style.zoom.minimap.show' , def: true , type: ' checkbox' },
183+ { key: ' style.zoom.preview.enable' , def: true , type: ' checkbox' },
148184
149185 { key: ' style.title.text' , def: ' At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis' , type: ' text' },
150186 { key: ' style.title.color' , def: ' #1A1A1A' , type: ' color' },
@@ -238,13 +274,29 @@ const config = computed(() => {
238274 theme: currentTheme .value ,
239275 style: {
240276 ... c .style ,
277+ zoom: {
278+ ... c .style .zoom ,
279+ useDefaultFormat: true ,
280+ timeFormat: ' yyyy-MM-dd' ,
281+ customFormat : ({ datapoint, timeLabel }) => {
282+ return timeLabel
283+ }
284+ },
285+ tooltip: {
286+ ... c .style .tooltip ,
287+ useDefaultTimeFormat: false ,
288+ timeFormat: ' yyyy-MM-dd'
289+ },
241290 layout: {
242291 ... c .style .layout ,
243292 grid: {
244293 ... c .style .layout .grid ,
245294 xAxis: {
246295 ... c .style .layout .grid .xAxis ,
247296 dataLabels: {
297+ showOnlyFirstAndLast: false ,
298+ showOnlyAtModulo: true ,
299+ modulo: 12 ,
248300 datetimeFormatter: {
249301 enable: true
250302 }
@@ -266,7 +318,13 @@ onMounted(async () => {
266318 const img = await local .value .getImage ();
267319 console .log (img)
268320 }
269- })
321+ });
322+
323+ const selectedX = ref (undefined );
324+
325+ function selectX ({ datapoint, index, indexLabel}) {
326+ selectedX .value = index;
327+ }
270328
271329 </script >
272330
@@ -312,7 +370,7 @@ onMounted(async () => {
312370 <template #title >VueUiCandlestick</template >
313371
314372 <template #local >
315- <LocalVueUiCandlestick :dataset =" dataset" :config =" isPropsToggled ? alternateConfig : config" :key =" `local_${step}`" ref =" local" >
373+ <LocalVueUiCandlestick :selectedXIndex = " selectedX " @selectX = " selectX " : dataset =" dataset" :config =" isPropsToggled ? alternateConfig : config" :key =" `local_${step}`" ref =" local" >
316374 <!-- <template #optionPdf>
317375 PRINT PDF
318376 </template>
@@ -339,7 +397,7 @@ onMounted(async () => {
339397 </template >
340398
341399 <template #VDUI-local >
342- <LocalVueDataUi component =" VueUiCandlestick" :dataset =" isPropsToggled ? alternateDataset : dataset" :config =" isPropsToggled ? alternateConfig : config" :key =" `VDUI-lodal_${step}`" ref =" vduiLocal" >
400+ <LocalVueDataUi :selectedXIndex = " selectedX " @selectX = " selectX " component =" VueUiCandlestick" :dataset =" isPropsToggled ? alternateDataset : dataset" :config =" isPropsToggled ? alternateConfig : config" :key =" `VDUI-lodal_${step}`" ref =" vduiLocal" >
343401 <!-- <template #svg="{ svg }">
344402 <circle :cx="svg.width / 2" :cy="svg.height / 2" :r="30" fill="#42d392" />
345403 <text :x="svg.width / 2" :y="svg.height / 2" text-anchor="middle">#SVG</text>
0 commit comments