1+ <script setup>
2+ import { ref , computed } from " vue" ;
3+ import LocalVueUiCandlestick from ' ../src/components/vue-ui-candlestick.vue' ;
4+ import LocalVueDataUi from ' ../src/components/vue-data-ui.vue' ;
5+ import Box from " ./Box.vue" ;
6+ import convertArrayToObject from " ./convertModel" ;
7+ import VueUiCandlestick from " ../src/components/vue-ui-candlestick.vue" ;
8+
9+ const dataset = ref ([
10+ [" 2024-01-01" , 56 , 120 , 40 , 110 , 1250 ],
11+ [" 2024-02-01" , 110 , 150 , 80 , 98 , 2200 ],
12+ [" 2024-03-01" , 98 , 155 , 75 , 103 , 3500 ],
13+ [" 2024-04-01" , 103 , 115 , 102 , 102 , 999 ],
14+ [" 2024-05-01" , 102 , 135 , 72 , 85 , 3216 ],
15+ [" 2024-06-01" , 85 , 162 , 65 , 107 , 4315 ],
16+ [" 2024-07-01" , 107 , 134 , 99 , 112 , 2561 ],
17+ [" 2024-08-01" , 112 , 125 , 112 , 120 , 669 ],
18+ [" 2024-09-01" , 120 , 113 , 76 , 89 , 2591 ],
19+ [" 2024-10-01" , 89 , 150 , 85 , 125 , 2881 ],
20+ [" 2024-11-01" , 125 , 130 , 45 , 92 , 1972 ],
21+ [" 2024-12-01" , 92 , 120 , 35 , 75 , 3599 ],
22+ [" 2024-13-01" , 75 , 80 , 26 , 45 , 5881 ],
23+ [" 2024-14-01" , 45 , 60 , 20 , 30 , 2881 ],
24+ [" 2024-15-01" , 30 , 120 , 10 , 105 , 2881 ],
25+ ]);
26+
27+ const model = ref ([
28+ { key: ' useCssAnimation' , def: true , type: ' checkbox' },
29+ { key: ' style.fontFamily' , def: " inherit" , type: ' text' },
30+ { key: ' style.backgroundColor' , def: ' #FFFFFF' , type: ' color' },
31+ { key: ' style.color' , def: ' #1A1A1A' , type: ' color' },
32+ { key: ' style.height' , def: 316 , type: ' number' , min: 100 , max: 1000 },
33+ { key: ' style.width' , def: 512 , type: ' number' , min: 100 , max: 1000 },
34+ { key: ' style.layout.useDiv' , def: true , type: ' checkbox' }, // DEPRECATED
35+ { key: ' style.layout.padding.top' , def: 36 , type: ' number' , min: 0 , max: 100 },
36+ { key: ' style.layout.padding.right' , def: 48 , type: ' number' , min: 0 , max: 100 },
37+ { key: ' style.layout.padding.bottom' , def: 36 , type: ' number' , min: 0 , max: 100 },
38+ { key: ' style.layout.padding.left' , def: 48 , type: ' number' , min: 0 , max: 100 },
39+ { key: ' style.layout.selector.color' , def: ' #1A1A1A' , type: ' color' },
40+ { key: ' style.layout.selector.opacity' , def: 10 , type: ' range' , min: 0 , max: 100 },
41+ { key: ' style.layout.grid.show' , def: true , type: ' checkbox' },
42+ { key: ' style.layout.grid.stroke' , def: ' #e1e5e8' , type: ' color' },
43+ { key: ' style.layout.grid.strokeWidth' , def: 0.5 , type: ' range' , min: 0 , max: 12 , step: 0.5 },
44+ { key: ' style.layout.grid.xAxis.dataLabels.show' , def: true , type: ' checkbox' },
45+ { key: ' style.layout.grid.xAxis.dataLabels.fontSize' , def: 4 , type: ' number' , min: 4 , max: 12 },
46+ { key: ' style.layout.grid.xAxis.dataLabels.color' , def: ' #1A1A1A' , type: ' color' },
47+ { key: ' style.layout.grid.xAxis.dataLabels.offsetY' , def: 0 , type: ' number' , min: - 100 , max: 100 },
48+ { key: ' style.layout.grid.xAxis.dataLabels.bold' , def: false , type: ' checkbox' },
49+ { key: ' style.layout.grid.yAxis.dataLabels.show' , def: true , type: ' checkbox' },
50+ { key: ' style.layout.grid.yAxis.dataLabels.fontSize' , def: 4 , type: ' number' , min: 4 , max: 12 },
51+ { key: ' style.layout.grid.yAxis.dataLabels.color' , def: ' #1A1A1A' , type: ' color' },
52+ { key: ' style.layout.grid.yAxis.dataLabels.offsetX' , def: 0 , type: ' number' , min: - 100 , max: 100 },
53+ { key: ' style.layout.grid.yAxis.dataLabels.bold' , def: false , type: ' checkbox' },
54+ { key: ' style.layout.grid.yAxis.dataLabels.steps' , def: 10 , type: ' number' , min: 2 , max: 20 },
55+ { key: ' style.layout.grid.yAxis.dataLabels.prefix' , def: ' P' , type: ' text' },
56+ { key: ' style.layout.grid.yAxis.dataLabels.suffix' , def: ' S' , type: ' text' },
57+ { key: ' style.layout.wick.stroke' , def: ' #1A1A1A' , type: ' color' },
58+ { key: ' style.layout.wick.strokeWidth' , def: 0.5 , type: ' number' , min: 0 , max: 12 , step: 0.5 },
59+ { key: ' style.layout.wick.extremity.shape' , def: ' line' , type: ' select' , options: [' line' , ' circle' ]},
60+ { key: ' style.layout.wick.extremity.size' , def: ' auto' , type: ' select' , options: [' auto' , 5 , 10 , 20 , 40 ]},
61+ { key: ' style.layout.wick.extremity.color' , def: ' #1A1A1A' , type: ' color' },
62+ { key: ' style.layout.candle.borderRadius' , def: 1 , type: ' number' , min: 0 , max: 12 },
63+ { key: ' style.layout.candle.stroke' , def: ' #1A1A1A' , type: ' color' },
64+ { key: ' style.layout.candle.strokeWidth' , def: 0.5 , type: ' number' , min: 0.5 , max: 12 , step: 0.5 },
65+ { key: ' style.layout.candle.colors.bearish' , def: ' #dc3912' , type: ' color' },
66+ { key: ' style.layout.candle.colors.bullish' , def: ' #109618' , type: ' color' },
67+ { key: ' style.layout.candle.gradient.show' , def: true , type: ' checkbox' },
68+ { key: ' style.layout.candle.gradient.intensity' , def: 40 , type: ' range' , min: 0 , max: 100 }, // not applied ?
69+ { key: ' style.layout.candle.gradient.underlayer' , def: ' #FFFFFF' , type: ' color' },
70+ { key: ' style.layout.candle.widthRatio' , def: 0.5 , type: ' number' , min: 0.1 , max: 1 , step: 0.1 },
71+ { key: ' style.zoom.show' , def: true , type: ' checkbox' },
72+ { key: ' style.zoom.color' , def: ' #CCCCCC' , type: ' color' }, // not applied
73+ { key: ' style.title.text' , def: ' At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis' , type: ' text' },
74+ { key: ' style.title.color' , def: ' #1A1A1A' , type: ' color' },
75+ { key: ' style.title.fontSize' , def: 20 , type: ' number' , min: 8 , max: 48 },
76+ { key: ' style.title.bold' , def: true , type: ' checkbox' },
77+ { key: ' style.title.subtitle.text' , def: ' At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis' , type: ' text' },
78+ { key: ' style.title.subtitle.color' , def: ' #CCCCCC' , type: ' color' },
79+ { key: ' style.title.subtitle.fontSize' , def: 16 , type: ' range' , min: 8 , max: 48 },
80+ { key: ' style.title.subtitle.bold' , def: false , type: ' checkbox' },
81+ { key: ' style.tooltip.show' , def: true , type: ' checkbox' },
82+ { key: ' style.tooltip.backgroundColor' , def: ' #FFFFFF' , type: ' color' },
83+ { key: ' style.tooltip.color' , def: ' #1A1A1A' , type: ' color' },
84+ { key: ' style.tooltip.fontSize' , def: 14 , type: ' number' , min: 6 , max: 24 },
85+ { key: ' style.tooltip.showValue' , def: true , type: ' checkbox' },
86+ { key: ' style.tooltip.roundingValue' , def: 0 , type: ' number' , min: 0 , max: 6 },
87+ { key: ' style.tooltip.prefix' , def: ' P' , type: ' text' },
88+ { key: ' style.tooltip.suffix' , def: ' S' , type: ' text' },
89+ { key: ' translations.period' , def: ' Period' , def: ' text' },
90+ { key: ' translations.open' , def: ' Open' , def: ' text' },
91+ { key: ' translations.high' , def: ' High' , def: ' text' },
92+ { key: ' translations.low' , def: ' Low' , def: ' text' },
93+ { key: ' translations.last' , def: ' Last' , def: ' text' },
94+ { key: ' translations.volume' , def: ' Volume' , def: ' text' },
95+ { key: ' userOptions.show' , def: true , type: ' checkbox' },
96+ { key: ' table.show' , def: false , type: ' checkbox' , label: ' show' , category: ' table' },
97+ { key: ' table.responsiveBreakpoint' , def: 400 , type: ' number' , min: 300 , max: 800 },
98+ { key: ' table.th.backgroundColor' , def: ' #FFFFFF' , type: ' color' },
99+ { key: ' table.th.color' , def: ' #1A1A1A' , type: ' color' },
100+ { key: ' table.th.outline' , def: ' none' , type: ' text' },
101+ { key: ' table.td.backgroundColor' , def: ' #FFFFFF' , type: ' color' },
102+ { key: ' table.td.color' , def: ' #1A1A1A' , type: ' color' },
103+ { key: ' table.td.outline' , def: ' none' , type: ' text' },
104+ { key: ' table.td.roundingValue' , def: 2 , type: ' number' , min: 0 , max: 6 },
105+ { key: ' table.td.prefix' , def: ' P' , type: ' text' },
106+ { key: ' table.td.suffix' , def: ' S' , type: ' text' },
107+ ])
108+
109+ const testCustomTooltip = ref (false );
110+
111+ const config = computed (() => {
112+ const c = convertArrayToObject (model .value );
113+ if (testCustomTooltip .value ) {
114+ return {
115+ ... c,
116+ style: {
117+ ... c .style ,
118+ tooltip: {
119+ ... c .style .tooltip ,
120+ customFormat : ({ datapoint }) => {
121+ let html = ' ' ;
122+ console .log (datapoint);
123+ return " test"
124+ }
125+ }
126+ }
127+
128+ }
129+ } else {
130+ return {
131+ ... c
132+ }
133+ }
134+ });
135+
136+ const step = ref (0 )
137+
138+ </script >
139+
140+ <template >
141+ <div style =" margin : 12px 0 " >
142+ <input type =" checkbox" v-model =" testCustomTooltip" id =" custom-tooltip" />
143+ <label for =" custom-tooltip" style =" color :#CCCCCC " >Test custom tooltip</label >
144+ </div >
145+
146+ <Box >
147+ <template #title >VueUiCandlestick</template >
148+
149+ <template #local >
150+ <LocalVueUiCandlestick :dataset =" dataset" :config =" config" :key =" `local_${step}`" >
151+ <template #svg =" { svg } " >
152+ <circle :cx =" svg.width / 2" :cy =" svg.height / 2" :r =" 30" fill =" #42d392" />
153+ <text :x =" svg.width / 2" :y =" svg.height / 2" text-anchor =" middle" >#SVG</text >
154+ </template >
155+ <template #legend =" { legend } " >
156+ #LEGEND
157+ <div style =" font-size : 8px " >
158+ {{ legend }}
159+ </div >
160+ </template >
161+ <template #tooltip-before =" { datapoint , seriesIndex , series , config , bars , lines , plots } " >
162+ #BEFORE {{ series.name }}
163+ </template >
164+ <template #tooltip-after =" { datapoint , seriesIndex , series , config , bars , lines , plots } " >
165+ #AFTER {{ series.name }}
166+ </template >
167+ </LocalVueUiCandlestick >
168+ </template >
169+
170+ <template #VDUI-local >
171+ <LocalVueDataUi component =" VueUiCandlestick" :dataset =" dataset" :config =" config" :key =" `VDUI-lodal_${step}`" >
172+ <template #svg =" { svg } " >
173+ <circle :cx =" svg.width / 2" :cy =" svg.height / 2" :r =" 30" fill =" #42d392" />
174+ <text :x =" svg.width / 2" :y =" svg.height / 2" text-anchor =" middle" >#SVG</text >
175+ </template >
176+ <template #legend =" { legend } " >
177+ #LEGEND
178+ <div style =" font-size : 8px " >
179+ {{ legend }}
180+ </div >
181+ </template >
182+ <template #tooltip-before =" { datapoint , seriesIndex , series , config , bars , lines , plots } " >
183+ #BEFORE {{ series.name }}
184+ </template >
185+ <template #tooltip-after =" { datapoint , seriesIndex , series , config , bars , lines , plots } " >
186+ #AFTER {{ series.name }}
187+ </template >
188+ </LocalVueDataUi >
189+ </template >
190+
191+ <template #build >
192+ <VueUiCandlestick :dataset =" dataset" :config =" config" :key =" `build_${step}`" >
193+ <template #svg =" { svg } " >
194+ <circle :cx =" svg.width / 2" :cy =" svg.height / 2" :r =" 30" fill =" #42d392" />
195+ <text :x =" svg.width / 2" :y =" svg.height / 2" text-anchor =" middle" >#SVG</text >
196+ </template >
197+ <template #legend =" { legend } " >
198+ #LEGEND
199+ <div style =" font-size : 8px " >
200+ {{ legend }}
201+ </div >
202+ </template >
203+ <template #tooltip-before =" { datapoint , seriesIndex , series , config , bars , lines , plots } " >
204+ #BEFORE {{ series.name }}
205+ </template >
206+ <template #tooltip-after =" { datapoint , seriesIndex , series , config , bars , lines , plots } " >
207+ #AFTER {{ series.name }}
208+ </template >
209+ </VueUiCandlestick >
210+ </template >
211+
212+ <template #VDUI-build >
213+ <VueDataUi component =" VueUiCandlestick" :dataset =" dataset" :config =" config" :key =" `VDUI-build_${step}`" >
214+ <template #svg =" { svg } " >
215+ <circle :cx =" svg.width / 2" :cy =" svg.height / 2" :r =" 30" fill =" #42d392" />
216+ <text :x =" svg.width / 2" :y =" svg.height / 2" text-anchor =" middle" >#SVG</text >
217+ </template >
218+ <template #legend =" { legend } " >
219+ #LEGEND
220+ <div style =" font-size : 8px " >
221+ {{ legend }}
222+ </div >
223+ </template >
224+ <template #tooltip-before =" { datapoint , seriesIndex , series , config , bars , lines , plots } " >
225+ #BEFORE {{ series.name }}
226+ </template >
227+ <template #tooltip-after =" { datapoint , seriesIndex , series , config , bars , lines , plots } " >
228+ #AFTER {{ series.name }}
229+ </template >
230+ </VueDataUi >
231+ </template >
232+
233+ <template #knobs >
234+ <div
235+ style =" display : flex ; flex-direction : row ; flex-wrap :wrap ; align-items :center ; width : 100% ; color : #CCCCCC ; gap :24px ;" >
236+ <div v-for =" knob in model" >
237+ <label style =" font-size : 10px " >{{ knob.key }}</label >
238+ <div
239+ style =" display :flex ; flex-direction :row ; flex-wrap : wrap ; align-items :center ; gap :6px ; height : 40px " >
240+ <input v-if =" !['none', 'select'].includes(knob.type)" :step =" knob.step" :type =" knob.type" :min =" knob.min ?? 0"
241+ :max =" knob.max ?? 0" v-model =" knob.def" @change =" step += 1" >
242+ <select v-if =" knob.type === 'select'" v-model =" knob.def" @change =" step += 1" >
243+ <option v-for =" opt in knob.options" >{{ opt }}</option >
244+ </select >
245+ </div >
246+ </div >
247+ </div >
248+ </template >
249+
250+ <template #config >
251+ {{ config }}
252+ </template >
253+ </Box >
254+ </template >
0 commit comments